/*
 * Entry stylesheet. tokens.css and components.css come verbatim from the design handoff
 * (docs/design/handoff, P031) and are imported from app.js before this file.
 * Only small app-level additions live here, built from the same tokens; anything bigger goes back to the design.
 */

/* Elements hidden with the HTML attribute stay hidden even when a component sets display. */
[hidden] {
  display: none !important;
}

/* Language menu (_lang_switch.html.twig, P034): a disclosure button with the current language and a list of every
   interface language in its own words. Tokens and the hard shadow of the design system; the list opens below the
   button in headers and above it in the footer, in one column on phones and two from 480 px. */
.lang-menu {
  position: relative;
}

.lang-menu__toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  min-block-size: var(--size-touch);
  padding: 0 var(--space-2);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-control);
  background: var(--color-surface);
  color: var(--color-text);
  font-size: var(--font-size-small);
  font-weight: var(--font-weight-bold);
  cursor: pointer;
  list-style: none;
}

.lang-menu__toggle::-webkit-details-marker {
  display: none;
}

.lang-menu__toggle:hover {
  background: var(--color-surface-muted);
}

.lang-menu__toggle:focus-visible {
  outline: var(--border-width-heavy) solid var(--color-focus);
  outline-offset: 2px;
}

/* Below 480 px the button is the globe alone (44 px); the language name stays for screen readers. */
.lang-menu__toggle {
  min-inline-size: var(--size-touch);
  justify-content: center;
}

.lang-menu__current {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.lang-menu__chevron {
  transition: transform var(--duration-fast);
}

.lang-menu__details[open] .lang-menu__chevron {
  transform: rotate(180deg);
}

.lang-menu__list {
  position: absolute;
  z-index: var(--z-dialog);
  inset-block-start: calc(100% + var(--space-1));
  inset-inline-end: 0;
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-0-5);
  inline-size: max-content;
  min-inline-size: 13rem;
  max-inline-size: calc(100vw - 2 * var(--gutter));
  max-block-size: min(70vh, 30rem);
  margin: 0;
  padding: var(--space-1);
  overflow-y: auto;
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-card);
  background: var(--color-surface);
  box-shadow: var(--shadow-hard-sm);
  list-style: none;
}

.lang-menu--footer .lang-menu__list {
  inset-block: auto calc(100% + var(--space-1));
  inset-inline: 0 auto;
}

.lang-menu__link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  min-block-size: var(--size-touch);
  padding: 0 var(--space-2);
  border-radius: var(--radius-sm);
  color: var(--color-text);
  font-size: var(--font-size-small);
  font-weight: var(--font-weight-semibold);
  text-decoration: none;
  white-space: nowrap;
}

.lang-menu__link:hover {
  background: var(--color-surface-muted);
}

.lang-menu__link[aria-current="page"] {
  background: var(--color-accent-soft);
  font-weight: var(--font-weight-extrabold);
}

@media (min-width: 480px) {
  .lang-menu__current {
    position: static;
    inline-size: auto;
    block-size: auto;
    overflow: visible;
    clip-path: none;
  }

  .lang-menu__list {
    grid-template-columns: repeat(2, minmax(11rem, 1fr));
  }
}

/* Long compound words in the large landing titles (DE "Ernährungstagebuch", P034): German is hyphenated, and no word in
   any language may push the page sideways; languages that fit keep their line breaks. */
.landing-hero__title,
.landing-cta__title {
  max-width: 100%;
  overflow-wrap: break-word;
}

/* Languages with long compound words (DE, NL, SV, DA, NB, FI, HU) hyphenate the big titles. */
.landing-hero__title:is(:lang(de), :lang(nl), :lang(sv), :lang(da), :lang(nb), :lang(fi), :lang(hu)),
.landing-cta__title:is(:lang(de), :lang(nl), :lang(sv), :lang(da), :lang(nb), :lang(fi), :lang(hu)) {
  hyphens: auto;
}

/* Long legal texts (no typography rules in the handoff yet, OPEN_QUESTIONS D.25). */
.legal h2 {
  font-size: var(--font-size-title-sm);
  line-height: var(--line-height-snug);
  font-weight: var(--font-weight-black);
  font-stretch: var(--font-stretch-compact);
}

.legal ul,
.legal ol {
  margin: 0;
  padding-inline-start: var(--space-5);
  display: grid;
  gap: var(--space-1-5);
}

/* Connectivity banner from base.html.twig (no design component). */
.offline-banner {
  margin: 0;
  padding: var(--space-2) var(--space-4);
  background: var(--color-warning-bg);
  color: var(--color-text);
  font-size: var(--font-size-small);
  text-align: center;
}

/* In the public header the language menu sits on the right, next to the account links. */
.landing-header__inner > .lang-menu {
  margin-inline-start: auto;
}

.landing-header__inner > .lang-menu + .landing-header__nav {
  margin-inline-start: 0;
}

/* Week summary on desktop (handoff §7 .summary-layout--week, "Etap 4: pozostało"): the grid of components.css shares
   its rows between the columns, so when the numbers on the left (total, limit, balance with "How we count" open) are
   taller than the chart, "Days" starts only below the balance and leaves a gap under the chart. Two independent
   columns instead: each item floats to its side and stacks right under the previous one of that side, in the same
   5fr | 7fr proportions and gaps. HTML order (= reading and focus order) stays the order of the phone layout. */
@container app (min-width: 1024px) {
  .summary-layout--week {
    display: flow-root;
  }

  .summary-layout--week > .summary-layout__total,
  .summary-layout--week > .summary-layout__limit,
  .summary-layout--week > .summary-layout__balance,
  .summary-layout--week > .summary-layout__comment {
    float: inline-start;
    clear: inline-start;
    inline-size: calc((100% - var(--space-8)) * 5 / 12);
    margin-block-end: var(--space-3);
  }

  .summary-layout--week > .summary-layout__chart,
  .summary-layout--week > .summary-layout__days {
    float: inline-end;
    clear: inline-end;
    inline-size: calc((100% - var(--space-8)) * 7 / 12);
    margin-block-end: var(--space-3);
  }
}

/* Day view in place (app/day.html.twig): the wrapper of the sheets that the Turbo Stream answers swap adds no box. */
.day-dialogs {
  display: contents;
}

/* "Pick a day" (design summary-month.html, state 4): <turbo-frame> is inline by default; in the sheet and on its
   no-JS page it stacks the period arrows and the calendar like the other sheet content (gap of .sheet[open]). */
.day-calendar {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.day-calendar__placeholder {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

/* Landing after the market audit (P039, docs/design/reviews/2026-10-31_landing-audit.md §3). Design tokens only. */
.landing-hero__micro,
.landing-cta__micro {
  color: var(--color-text-secondary);
  font-size: var(--font-size-small);
  line-height: var(--line-height-body);
}

.landing-cta__micro {
  color: inherit;
  opacity: 0.85;
}

/* Short facts in a row that wraps into a column (hero, "Who sees what"). */
.info-list--inline {
  flex-flow: row wrap;
  gap: var(--space-2) var(--space-5);
}

.info-list--inline .info-list__item {
  font-size: var(--font-size-small);
  font-weight: var(--font-weight-semibold);
}

.landing-section__lead {
  max-inline-size: 40rem;
  margin-block-end: var(--space-5);
  color: var(--color-text-secondary);
  font-size: var(--font-size-lead);
  line-height: var(--line-height-body);
}

/* "Honest numbers": four cards, two per row from 768 px (the three-card grid of the package is for three). */
@container page (min-width: 768px) {
  .landing-benefits--4 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@container page (min-width: 1024px) {
  .landing-benefits--4 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.landing-data {
  margin-block: var(--space-6) var(--space-3);
}

.landing-operator {
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
}

.landing-operator a {
  color: inherit;
  font-weight: var(--font-weight-bold);
}

/* Footer: two link groups and the trademark note (P039). */
.landing-footer__navs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-8);
}

.landing-footer__nav {
  flex-direction: column;
  align-items: flex-start;
}

.landing-footer__nav .landing-footer__link {
  justify-content: flex-start;
}

.landing-footer__legal {
  flex-basis: 100%;
  color: var(--color-text-muted);
  font-size: var(--font-size-caption);
  line-height: var(--line-height-body);
}

/* Public connection guide /connect (P039). */
.connect-guide {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.connect-guide__assistant {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding-block-start: var(--space-4);
  border-block-start: var(--border-width) solid var(--color-border);
}

.connect-guide__title {
  font-size: var(--font-size-title-sm);
  font-weight: var(--font-weight-extrabold);
}

/* Amount + unit (.field-row, 1 : 2, handoff components.html "Więcej szczegółów"): an item kept "per portion" adds a 4th
   unit (g · ml · pcs · portion). Four segments do not fit in two thirds of a phone column (at 390 px "porzione" or
   "Portion" overflow their 49 px, at 320 px every label does), so below the tablet width the unit gets its own row with
   4 px at the sides of a label; in a column narrower than 360 px (phones of 320 px) the four segments form two rows of
   two, because even a full row leaves 60 px per segment and the selected Italian "porzione" needs 61 px. */
@container app (max-width: 767px) {
  .field-row:has(.choice-seg__option:nth-child(4)) {
    grid-template-columns: minmax(0, 1fr);
  }

  .choice-seg:has(.choice-seg__option:nth-child(4)) .choice-seg__label {
    padding-inline: var(--space-1);
  }
}

@container app (max-width: 359px) {
  .choice-seg:has(.choice-seg__option:nth-child(4)) {
    grid-auto-flow: row;
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* Multi-line field (_form.html.twig textarea: "Assumptions" in Energy needs). The handoff only has the one-line .input
   (padding 0 at the top and bottom, the height comes from min-block-size), so in a <textarea> the text touched the
   frame. Same frame and font, the room of a one-line field above and below the text, resized only downwards. */
textarea.input {
  display: block;
  padding-block: var(--space-3);
  resize: vertical;
}

/* Long call-to-action labels in some languages wrap instead of pushing the page sideways at 320 px (P039). */
.landing-hero__actions .btn,
.landing-cta__button {
  max-inline-size: 100%;
  white-space: normal;
  text-wrap: balance;
}

/* Meals prepared for later (P045): visibly apart from what was eaten, on a plain background. */
.planned-list {
  display: grid;
  gap: var(--space-3);
  margin: var(--space-3) 0 0;
  padding: 0;
  list-style: none;
}

.planned-meal {
  padding: var(--space-4);
  border: var(--border-width) dashed var(--color-border);
  border-radius: var(--radius-lg);
}

.planned-meal__head {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--space-2);
  margin: 0;
}

.planned-meal__label {
  min-inline-size: 0;
  font-weight: var(--font-weight-bold);
  overflow-wrap: anywhere;
}

.planned-meal__items {
  margin: var(--space-1) 0 var(--space-3);
  color: var(--color-text-secondary);
  font-size: 0.875rem;
}

.planned-estimate {
  margin-block-start: var(--space-3);
  font-weight: var(--font-weight-bold);
}

.planned-meal__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

/* Friends group (P043): one card per person, stats in three columns that also hold long labels at 320 px. */
.group-week__range {
  margin-block-end: var(--space-3);
  color: var(--color-text-muted);
}

.group-week__note {
  margin-block-start: var(--space-3);
}

.group-board {
  display: grid;
  gap: var(--space-3);
  margin: 0;
  padding: 0;
  list-style: none;
}

.group-row {
  padding: var(--space-4);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
}

.group-row--you {
  background: var(--color-accent-soft);
}

.group-row__head {
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  margin: 0;
}

.group-row__place {
  flex: none;
  font-size: var(--font-size-title-sm);
  font-weight: var(--font-weight-extrabold);
}

.group-row__name {
  min-inline-size: 0;
  font-weight: var(--font-weight-bold);
  overflow-wrap: anywhere;
}

.group-row__you {
  color: var(--color-text-secondary);
  font-weight: normal;
}

.group-row__stats {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-2);
  margin: var(--space-3) 0;
}

/* Numbers stay on one line when a long label wraps to two. */
.group-row__stats > div {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

.group-row__stats dt {
  color: var(--color-text-secondary);
  font-size: 0.8125rem;
  overflow-wrap: anywhere;
  hyphens: auto;
}

.group-row__stats dd {
  margin: 0;
  font-size: var(--font-size-title-sm);
  font-weight: var(--font-weight-extrabold);
}

.group-row__today {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1) var(--space-2);
  margin: 0;
  font-size: 0.875rem;
}

.group-row__remove {
  margin-inline-start: auto;
}

.group-sharing__hidden {
  margin-block: var(--space-3);
}

.group-invite,
.group-sharing {
  margin-block: var(--space-5);
}

.group-invite__new {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin-block-start: var(--space-3);
}

.today__group {
  margin-block-start: var(--space-4);
}

/* "No searching" comparison on the landing (P041): the steps of a database counter next to one message. */
.landing-compare {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr));
  gap: var(--space-4);
  margin-block-start: var(--space-5);
}

.landing-compare__col {
  padding: var(--space-5);
  border: var(--border-width) solid var(--color-border-subtle);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
}

.landing-compare__col--new {
  border-color: var(--color-border);
  background: var(--color-accent-soft);
}

.landing-compare__title {
  margin-block-end: var(--space-3);
  font-size: var(--font-size-title-sm);
  font-weight: var(--font-weight-extrabold);
}

.landing-compare__list {
  display: grid;
  gap: var(--space-2);
  margin: 0;
  padding-inline-start: var(--space-5);
  color: var(--color-text-secondary);
  list-style: decimal;
}

.landing-compare__col--new .info-list {
  font-weight: var(--font-weight-bold);
}

/* The headline is two sentences (P041): the promise in full size, how it works on its own line below it. */
.landing-hero__how {
  display: block;
  margin-block-start: var(--space-3);
  font-size: 0.56em;
  line-height: 1.2;
}

/* Landing demo (P041): message, thinking, saved, diary. The default state is the finished picture, so without JS or with
   reduced motion nothing is missing; opacity and transform only, one play under 5 s (landing_demo_controller.js). */
.landing-hero__arrow {
  position: relative;
}

.landing-hero__dots {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 2px;
  opacity: 0;
}

.landing-hero__dots i {
  inline-size: 4px;
  block-size: 4px;
  border-radius: var(--radius-round);
  background: var(--color-text);
}

.landing-shot__badge {
  position: absolute;
  inset-block-start: var(--space-3);
  inset-inline-end: var(--space-3);
  padding: var(--space-1) var(--space-3);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-accent);
  color: var(--color-text-on-accent);
  font-weight: var(--font-weight-extrabold);
  opacity: 0;
}

@media (prefers-reduced-motion: no-preference) {
  .is-playing .landing-bubble--hero {
    animation: landing-rise 400ms ease-out 200ms both;
  }

  .is-playing .landing-hero__dots {
    animation: landing-think 1500ms linear 700ms both;
  }

  .is-playing .landing-hero__dots i {
    animation: landing-dot 500ms ease-in-out 700ms 3 alternate;
  }

  .is-playing .landing-hero__dots i:nth-child(2) {
    animation-delay: 850ms;
  }

  .is-playing .landing-hero__dots i:nth-child(3) {
    animation-delay: 1000ms;
  }

  .is-playing .landing-hero__arrow svg {
    animation: landing-fade 250ms ease-out 2200ms both;
  }

  .is-playing .landing-saved {
    animation: landing-pop 400ms cubic-bezier(0.2, 1.3, 0.5, 1) 2300ms both;
  }

  .is-playing .landing-shot__badge {
    animation: landing-badge 2000ms ease-out 2700ms both;
  }

  .landing-demo__row.is-playing .landing-bubble--user {
    animation: landing-rise 400ms ease-out 150ms both;
  }

  .landing-demo__row.is-playing .landing-bubble--assistant {
    animation: landing-rise 400ms ease-out 800ms both;
  }

  .landing-demo__row.is-playing .landing-demo__result {
    animation: landing-rise 400ms ease-out 1400ms both;
  }
}

@keyframes landing-rise {
  from {
    opacity: 0;
    transform: translateY(0.5rem);
  }
}

@keyframes landing-fade {
  from {
    opacity: 0;
  }
}

@keyframes landing-pop {
  from {
    opacity: 0;
    transform: scale(0.85);
  }
}

@keyframes landing-think {
  0%,
  100% {
    opacity: 0;
  }

  8%,
  92% {
    opacity: 1;
  }
}

@keyframes landing-dot {
  to {
    transform: translateY(-3px);
  }
}

@keyframes landing-badge {
  0%,
  100% {
    opacity: 0;
    transform: scale(0.85);
  }

  12%,
  85% {
    opacity: 1;
    transform: none;
  }
}

/* Bottom navigation at 320 px (P040): the long labels of these languages ("Einstellungen", "Configurações",
   "Podsumowania") fit without the label tracking instead of ending in an ellipsis. */
.app-nav__label:is(:lang(de), :lang(da), :lang(nb), :lang(sv), :lang(nl), :lang(pt-BR), :lang(pl)) {
  letter-spacing: 0;
}
