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

html,
body,
h1,
h2,
h3,
p,
ul,
ol,
li,
table,
th,
td,
figure {
  margin: 0;
  padding: 0;
}

/* Nothing on this site should ever render wider than its container. This
   is the rule that actually prevents it - do not delete it in a future
   cleanup pass, even though more specific rules (e.g. .dish__media img)
   also constrain their own images; this is the backstop for everything
   else, including anything added later. */
img,
picture {
  display: block;
  max-width: 100%;
  height: auto;
}

/* Tokens -------------------------------------------------------------- */
:root {
  --green-deep: #1e4739;
  --paper: #ffffff;
  --ink: #2b2622;
  --brass: #c8901e;
  --sumac: #8c2f2a;
  --stone: #e4e2dc;

  --font-serif: Georgia, "Times New Roman", Times, serif;
  --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
    Helvetica, Arial, sans-serif;
  --font-arabic: "SF Arabic", "Geeza Pro", "Segoe UI", Tahoma,
    "Noto Naskh Arabic", sans-serif;

  --step--1: 0.875rem;
  --step-0: 1rem;
  --step-1: 1.25rem;
  --step-2: 1.563rem;
  --step-3: 1.953rem;
  --step-4: 2.441rem;
  --step-5: 3.052rem;

  /* COUPLED to the `sizes` string in eleventy.config.mjs (dishPictureShortcode).
     Both of these feed its breakpoint arithmetic - changing either without
     updating that string makes browsers pick the wrong image size, with no
     error anywhere. The arithmetic is written out in full there. */
  --container-max: 1100px;
  --container-pad: 1.5rem;
  /* The header reads as navigation more clearly when it uses more of a
     wide window than the 1100px body container does - see
     .site-header__inner, which uses this instead of .container. */
  --header-container-max: 1600px;
}

/* Shared container: header, hero and page content all align to this same
   max-width and left edge - see .site-header__inner, .hero__inner,
   .section, .page-title. */
.container {
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: var(--container-pad);
}

/* Arabic text, wherever it appears - a whole Arabic page (<html lang="ar">)
   or one inline snippet on a ro/en page (a dish's Arabic name, the header
   logo, the hero wordmark) - needs a font stack with real Arabic glyphs.
   Georgia (--font-serif) has none, so Arabic set in it silently falls back
   to whatever the browser picks on its own. Redefining --font-serif and
   --font-sans here fixes every rule that references them via var() for any
   descendant of a [lang="ar"] element; the direct `font-family` covers an
   element that has no font-family rule of its own to begin with. System
   fonts only, matching the rest of the site: SF Arabic/Geeza Pro (Apple),
   Segoe UI/Tahoma (Windows), Noto Naskh Arabic (Android). */
[lang="ar"] {
  --font-serif: var(--font-arabic);
  --font-sans: var(--font-arabic);
  font-family: var(--font-arabic);
}

/* Base ------------------------------------------------------------- */
/* Rubber-band overscroll (macOS/iOS) pulls the page past its own top or
   bottom and reveals the canvas behind it. overscroll-behavior: none stops
   the bounce outright; the background-colors below are a fallback for any
   browser that ignores that property, so the revealed strip reads as the
   header/footer's green rather than white. html's background is what
   actually paints that strip - but once html carries a background, body's
   no longer stretches to fill the viewport on a short page, so body needs
   an explicit min-height too (see the 404 page, the shortest one). Header
   and footer are both --green-deep, so this matches at both ends. */
html {
  overscroll-behavior: none;
  background-color: var(--green-deep);
}

body {
  background: var(--paper);
  background-color: var(--paper);
  min-height: 100vh;
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: var(--step-0);
  line-height: 1.6;
}

h1,
h2,
h3 {
  font-family: var(--font-serif);
  color: var(--green-deep);
  line-height: 1.25;
}

a {
  color: var(--ink);
}

a:focus-visible {
  outline: 2px solid var(--brass);
  outline-offset: 2px;
}

/* Header - navigation, not a banner: kept short and non-sticky. A solid
   brass rule along the bottom is what actually separates it from the hero
   (same green, otherwise no boundary) and from the page body. ------- */
.site-header {
  background: var(--green-deep);
  color: var(--paper);
  border-bottom: 3px solid var(--brass);
}

.site-header__inner {
  /* Its own wider container, not the shared 1100px .container - the logo
     and nav move outward together, staying aligned with each other, while
     the hero/body/footer below keep the narrower measure. */
  max-width: var(--header-container-max);
  margin-inline: auto;
  padding-inline: var(--container-pad);
  display: flex;
  flex-wrap: wrap;
  /* stretch (not center): the logo and nav both reach the same row height,
     which is what lets the active-page underline (below) sit a fixed,
     predictable distance above the header's own bottom rule. */
  align-items: stretch;
  justify-content: space-between;
  gap: 0.75rem;
  padding-top: 0.5rem;
  /* This bottom padding is what keeps the active-page underline clear of
     the header's own border-bottom - see .site-header__nav a below. */
  padding-bottom: 0.5rem;
  line-height: 1.2;
}

.site-header__name {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-family: var(--font-serif);
  font-size: var(--step-1);
  font-weight: bold;
  color: var(--paper);
  text-decoration: none;
}

/* .brand-ar (see _includes/logo.njk) is the wordmark itself, shared by the
   header and the chooser page. In the header it needs no rule of its own -
   it just inherits the size and color .site-header__name already sets on
   its parent <a>. On the chooser page it's sized up instead by the
   .chooser__wordmark modifier class, further down. */

/* .site-header__controls groups the page nav, the divider and the language
   switcher into one flex item so .site-header__inner's space-between still
   only ever balances two things (the logo and this group) - same layout
   this held before .site-header__nav wrapped only the 3 page links. Below
   640px, this wrapper is display: contents (see the mobile media query
   further down) so its three children can be repositioned independently
   into a two-row grid; a plain div has no ARIA role to lose by doing that,
   which is why the split lives here and not on <nav> itself. */
.site-header__controls {
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  gap: 2.5rem;
}

/* The 3 page links themselves - a real <nav> at every width, so the
   landmark and its aria-label survive the mobile layout below unchanged. */
.site-header__nav {
  display: flex;
  align-items: stretch;
  gap: 2.5rem;
}

.site-header__controls a {
  display: flex;
  align-items: center;
  min-height: 44px;
  font-family: var(--font-serif);
  font-size: calc(var(--step--1) * 1.25);
  color: var(--paper);
  text-decoration: none;
  /* Reserve the same 3px regardless of state so hover/active never shifts
     layout; only the color changes. This sits above the link's own bottom
     edge (not on it), so .site-header__inner's padding-bottom below it
     shows as a visible strip of green between this underline and
     .site-header's own border-bottom rule - two separate marks, not one
     thicker one. */
  border-bottom: 3px solid transparent;
}

.site-header__controls a:hover {
  color: var(--brass);
}

/* :focus-visible outline comes from the global `a:focus-visible` rule
   above - same 2px brass / 2px offset, no need to repeat it here. */

.site-header__controls a[aria-current="page"] {
  border-bottom-color: var(--brass);
}

/* Language switcher: a sibling of .site-header__nav inside
   .site-header__controls, so its <a> tags still pick up
   .site-header__controls a's sizing, color, hover and active-page
   underline for free (that selector matches any descendant <a>, nesting
   depth doesn't matter) - same treatment, no repeated rules. The divider
   is a plain vertical bar; width isn't a left/right concept, so it needs
   no logical-property treatment for RTL. */
.site-header__divider {
  width: 1px;
  align-self: stretch;
  background: var(--brass);
}

.lang-switch {
  display: flex;
  align-items: stretch;
  gap: 1.25rem;
}

/* Phone header: 2 rows instead of the 3 that .site-header__controls'
   flex-wrap was producing below ~640px (logo, then nav, then the switch
   left stranded on its own line with the divider orphaned in the empty
   space above it). Grid areas are logical, not physical - "logo" resolves
   to the inline-start cell and "switcher" to inline-end under dir="rtl"
   the same way flexbox already mirrors elsewhere on this site, so this
   needs no separate RTL rule. Unwrapping .site-header__controls (display:
   contents; a plain div, no ARIA role to lose) is what lets its three
   children - <nav>, the divider, .lang-switch - land in three different
   grid areas instead of moving together as one flex item. */
@media (max-width: 639.98px) {
  .site-header__inner {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-template-areas:
      "logo logo switcher"
      "nav nav nav";
    align-items: center;
    row-gap: 0;
    column-gap: 0.75rem;
    /* Tightened from the desktop 0.5rem/0.5rem. Every link below still
       reserves its own 44px via min-height, so this only removes the
       surrounding air, not any tap target. padding-bottom stays non-zero
       on purpose - it's the visible gap between the nav row's own
       active-page underline and .site-header's border-bottom rule below
       it (point 6); at 0 the two would merge into a single thicker line. */
    padding-top: 0.25rem;
    padding-bottom: 0.25rem;
  }

  .site-header__name {
    grid-area: logo;
    justify-self: start;
    /* Matches the 44px tap target every other header link gets, via the
       same mechanism (min-height, not extra margin) rather than shrinking
       it down to its own 24px text height now that it shares a tighter
       row. */
    min-height: 44px;
  }

  .site-header__controls {
    display: contents;
  }

  .site-header__divider {
    /* Only makes sense as a mark between nav and switcher when they share
       a row (point 2) - on its own row split, there's nothing left to
       divide. */
    display: none;
  }

  .site-header__nav {
    grid-area: nav;
    /* Full-width row now (see grid-template-areas above); space-between
       spreads the 3 links edge-to-edge instead of clustering them with
       the 2.5rem desktop gap, which is what "evenly spaced across the
       full width" means at this size. */
    justify-content: space-between;
    gap: 0;
  }

  .lang-switch {
    grid-area: switcher;
    justify-self: end;
  }
}

/* Hero - short, not a full screen; no background image ------------- */
.hero {
  background: var(--green-deep);
  color: var(--paper);
}

.hero__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  /* Tightened along with the padding below, now that both lines of text
     render smaller - the hero should get shorter overall, not hold
     smaller text in the same amount of box. */
  gap: 0.5rem;
  min-height: 12vh;
  padding-top: 1rem;
  padding-bottom: 1rem;
  text-align: center;
}

@media (min-width: 640px) {
  .hero__inner {
    min-height: 20vh;
  }
}

/* Headline: must render on exactly one line at 360px in all three
   languages without changing any text - measured directly (headless
   Chrome, real Georgia/Arabic font metrics), not estimated. Romanian is
   the actual tightest fit at that width (its longest word run leaves the
   least slack), not Arabic as usually assumed - 1.35rem/21.6px was
   measured at 3.9% margin under Romanian's own max-that-still-fits, and
   trimmed to 1.3rem/20.8px here for a bit more cross-browser safety
   margin, since font metrics can shift slightly outside this one
   measurement environment. English fits with more room to spare at that
   same size. Arabic has the most slack of the three (system Arabic faces
   render this string narrower here, not wider), so it gets its own larger
   floor below instead of being held down to Romanian's ceiling. */
.hero__headline {
  font-family: var(--font-serif);
  font-size: clamp(1.3rem, 5.4vw, 3.25rem);
  /* This is the page's <h1> (it was a <p> until the SEO pass - the homepage
     had no h1 at all and jumped straight to h2). The generic `h1, h2, h3`
     rule above would otherwise repaint it: --green-deep on the green hero
     makes it invisible, plus bold and line-height 1.25. These three
     declarations reassert the <p> appearance exactly, so the tag change is
     semantic only and pixel-identical. Don't drop them. */
  color: var(--paper);
  font-weight: 400;
  line-height: 1.6;
}

[lang="ar"] .hero__headline {
  /* Arabic's measured one-line ceiling at 360/390px (≈25.4px/≈27.8px)
     leaves real room above Romanian and English's shared floor; sized up
     to use it, with the same ~6% safety margin. */
  font-size: clamp(1.5rem, 6vw, 3.25rem);
}

/* Second line: free to wrap (unlike the headline), so it only needs to
   stay legible, not fit one line. All three values are half the
   headline's, so the headline holds a steady 2:1 over this line at every
   width rather than only at one:

     floor    0.75rem  vs 1.3rem  - a slightly larger ratio than half,
                                    since 12px is about as small as body
                                    copy should go
     preferred  2.7vw  vs 5.4vw   - exactly half
     ceiling 1.625rem  vs 3.25rem - exactly half

   The ceiling is the one that has to be derived rather than eyeballed.
   Both curves must reach their ceiling at the same viewport width or the
   ratio drifts apart above the lower one: 3.25rem/5.4vw caps at 963px, so
   this line's ceiling has to be 2.7vw of 963px = 26px = 1.625rem. At the
   1.1rem it used to be, it capped at 652px and stayed 17.6px while the
   headline kept growing to 52px, leaving 2.95:1 on any screen wider than
   a tablet - which read as too small next to the headline. Change one
   ceiling and recompute the other. */
.hero__statement {
  font-family: var(--font-serif);
  font-size: clamp(0.75rem, 2.7vw, 1.625rem);
  color: var(--paper);
  text-wrap: balance;
}

/* Solid brass block, used for the hero's "Vezi meniul" and for the two
   homepage calls to action (.cta-row, below) - a plain <a>, not a
   <button>; nothing on this site submits anything. */
.btn {
  display: inline-block;
  background: var(--brass);
  color: var(--paper);
  font-weight: bold;
  text-decoration: none;
  padding: 0.75rem 1.75rem;
}

.btn:hover {
  text-decoration: underline;
}

/* Sections / measure ------------------------------------------------- */
.section {
  padding-top: 2.5rem;
  padding-bottom: 2.5rem;
}

.page-title {
  padding-top: 2.5rem;
  font-size: var(--step-3);
}

.section__heading {
  font-size: var(--step-2);
  margin-bottom: 1.5rem;
}

.lede {
  max-width: 55ch;
  margin-inline: auto;
  margin-bottom: 1.5rem;
  font-family: var(--font-serif);
  font-size: 1.35rem;
  line-height: 1.7;
  text-align: center;
}

/* Homepage calls to action, side by side on desktop with a gap between,
   stacked and full-width on mobile (each .btn is a flex item here, so it
   stretches to fill the column's width via the container's default
   align-items: stretch). */
.cta-row {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

@media (min-width: 480px) {
  .cta-row {
    flex-direction: row;
    gap: 1.5rem;
  }

  .cta-row .btn {
    /* Row mode: sized to their own text, not stretched to fill. */
    align-self: flex-start;
  }
}

/* Dish rows ------------------------------------------------------- */
/* Column count follows available width instead of being pinned at a fixed
   number - a card never gets smaller than 260px, but it also never has to
   scale up to fill half the container just because the container is wide.
   No media query needed: auto-fill recalculates the column count at every
   width on its own. */
.dish-list {
  display: grid;
  /* COUPLED to the `sizes` string in eleventy.config.mjs (dishPictureShortcode):
     the 260px minimum and the gap below both feed its breakpoint arithmetic,
     together with --container-max and --container-pad. Change any of the four
     and that string must be recomputed - otherwise browsers download the
     wrong image size and nothing reports it. Arithmetic is spelled out
     there. */
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 1.5rem;
}

/* A vertical card at every width: photo on top, text below. This is
   deliberate, not a mobile fallback - a side-by-side layout needs the
   photo column and text column to agree on a height, and they never do
   (the text column's height depends on the description length). A single
   column has no second height to disagree with. */
.dish {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--stone);
  /* .dish-list is a grid; its default align-items: stretch already makes
     every card in a row match the tallest one. That gives this flex
     column real extra space to hand to .dish__body (flex: 1, below),
     which is what keeps every card's bottom edge flush regardless of how
     long its description runs. */
}

/* Every generated dish photo is already cropped to a square at build time
   (see eleventy.config.mjs) - no object-fit/aspect-ratio compensation needed on
   the image itself. background: var(--stone) belongs on .dish__placeholder
   only, further down - a real photo's wrapper carries no background, so
   nothing shows through regardless of how the card's height is resolved. */
.dish__media {
  aspect-ratio: 1 / 1;
}

.dish__media picture,
.dish__media img {
  display: block;
  width: 100%;
  height: auto;
}

.dish__placeholder {
  display: block;
  width: 100%;
  height: 100%;
  background: var(--stone);
}

.dish__body {
  display: flex;
  flex-direction: column;
  /* Top padding tightened relative to the other three sides - cards used
     to carry a small Arabic accent line (.dish__name-ar) above the heading
     here, and 1.25rem of top padding cleared room for it. That line is
     gone (markup and CSS both, see dish.njk), so the top no longer needs
     as much air as the sides/bottom still do. */
  padding: 0.75rem 1.25rem 1.25rem;
  flex: 1;
}

.dish__name {
  font-family: var(--font-serif);
  font-size: var(--step-2);
  margin-bottom: 1.25rem;
}

.dish__description {
  max-width: 60ch;
  font-size: var(--step--1);
  font-weight: normal;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
}

.dish__description p {
  margin: 0;
}

/* Contact ------------------------------------------------------- */
.contact-list {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 1rem;
  max-width: 28rem;
}

.contact-list a {
  display: block;
  border: 1px solid var(--stone);
  padding: 0.9rem 1.1rem;
  text-decoration: none;
  font-size: var(--step-1);
}

.contact-list a:hover {
  border-color: var(--brass);
}

.steps {
  padding-inline-start: 1.25rem;
  max-width: 60ch;
}

.steps li {
  margin-bottom: 0.5rem;
}

/* Footer ------------------------------------------------------- */
.site-footer {
  background: var(--green-deep);
  color: var(--paper);
}

.site-footer__inner {
  padding-top: 2.5rem;
  padding-bottom: 2.5rem;
}

.site-footer__note {
  max-width: 55ch;
  margin-inline: auto;
  font-family: var(--font-serif);
  font-size: var(--step-0);
  text-align: center;
}

@media (min-width: 640px) {
  .site-footer__note {
    font-size: var(--step-1);
  }
}

/* Language chooser (/) ------------------------------------------------- */
/* The only thing at the root - no header, no nav, no footer. A full-height
   green screen with a white card that reads as a dialog, because choosing
   a language is mandatory (there is nowhere else to go from here). */
.chooser {
  min-height: 100vh;
  background: var(--green-deep);
  color: var(--paper);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1.5rem;
  padding: 2rem 1.5rem;
  text-align: center;
}

.chooser__wordmark {
  font-size: clamp(1.75rem, 6vw, 2.5rem);
}

.chooser__card {
  background: var(--paper);
  color: var(--ink);
  border: 1px solid var(--stone);
  width: 100%;
  max-width: 28rem;
  padding: 2.5rem 2rem;
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.chooser__heading-en {
  font-family: var(--font-serif);
  font-size: var(--step-3);
  color: var(--green-deep);
  /* This is the chooser's <h1> (was a <p>; the page had no h1 at all). The
     generic `h1, h2, h3` rule sets line-height 1.25, and the UA default
     makes an h1 bold - the two declarations below restore the <p>
     appearance exactly, so the tag change is semantic only. Font-family and
     color are already asserted above, so those two need no restoring. */
  font-weight: 400;
  line-height: 1.6;
}

.chooser__heading-ar {
  font-size: var(--step-1);
  color: var(--ink);
  opacity: 0.75;
}

.chooser__links {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  margin-top: 0.5rem;
}

/* 404 -------------------------------------------------------------- */
/* Language-neutral, like the chooser: no header, no nav, no footer. */
.notfound {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1.5rem;
  padding: 2rem 1.5rem;
  text-align: center;
}

.notfound__name {
  font-family: var(--font-serif);
  color: var(--green-deep);
  font-size: var(--step-2);
  /* The 404's <h1> - same reasoning as .chooser__heading-en above: neutralise
     the generic h1 line-height and the UA bold so the tag change is
     semantic only. */
  font-weight: 400;
  line-height: 1.6;
}

.notfound__lines {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  font-size: var(--step-1);
}

.notfound__links {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 1rem;
  margin-top: 0.5rem;
}

