/* app/css/app.css — cely dizajnovy system appky (sand/teal #111110 / #0BD8B6; do 31. 8. 2026
   navy/mint #0A1A2F / #34F7D7 — remapovane na swatche zo style-guide obrazku, 208 literalov).
   Vynate z app/index.html 9. 8. 2026 vecer (Richardovo "nonstop na monolite").
   Wholesale presun, ZIADNA zmena pravidiel — bajt po bajte ten isty obsah, aky
   dovtedy niesol <style> blok. Nacitava sa <link rel="stylesheet"> na tom istom
   mieste <head>, takze poradie kaskady sa nemeni. */
/* ── Self-hosted brand type (Richard, 31. 8. 2026 — visual v2 design system) ──
   SIL OFL fonts, downloaded once from Google Fonts (latin + latin-ext subsets only —
   de-CH umlauts live in the U+0000-00FF latin block, sk/cs diacritics need latin-ext)
   and served same-origin from app/fonts/, because font-src 'self' in the CSP forbids
   fonts.googleapis.com / fonts.gstatic.com at runtime (ZIP30 H4 same rule that stripped
   the CDN Chart.js/Google-Fonts tags out of app/dashboard-dual-view.html). Four roles:
   Fraunces = brand/logo, Bricolage Grotesque = headings, IBM Plex Sans = UI & tables,
   Atkinson Hyperlegible Next = data readouts (temps, %, counts). */
@font-face {
  font-family: 'Fraunces';
  font-style: normal;
  font-weight: 600; font-display: swap;
  src: url('../assets/fonts/fraunces-600.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Fraunces';
  font-style: normal;
  font-weight: 700; font-display: swap;
  src: url('../assets/fonts/fraunces-700.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Bricolage Grotesque';
  font-style: normal;
  font-weight: 600;
  font-stretch: normal; font-display: swap;
  src: url('../assets/fonts/bricolage-600.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Bricolage Grotesque';
  font-style: normal;
  font-weight: 700;
  font-stretch: normal; font-display: swap;
  src: url('../assets/fonts/bricolage-700.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 400;
  font-stretch: normal; font-display: swap;
  src: url('../assets/fonts/ibmplexsans-400.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 500;
  font-stretch: normal; font-display: swap;
  src: url('../assets/fonts/ibmplexsans-500.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 600;
  font-stretch: normal; font-display: swap;
  src: url('../assets/fonts/ibmplexsans-600.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 700;
  font-stretch: normal; font-display: swap;
  src: url('../assets/fonts/ibmplexsans-700.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Atkinson Hyperlegible Next';
  font-style: normal;
  font-weight: 400; font-display: swap;
  src: url('../assets/fonts/atkinson-400.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Atkinson Hyperlegible Next';
  font-style: normal;
  font-weight: 700; font-display: swap;
  src: url('../assets/fonts/atkinson-700.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Bricolage Grotesque';
  font-style: normal;
  font-weight: 600;
  font-stretch: normal; font-display: swap;
  src: url('../assets/fonts/bricolage-600-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Bricolage Grotesque';
  font-style: normal;
  font-weight: 700;
  font-stretch: normal; font-display: swap;
  src: url('../assets/fonts/bricolage-700-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 400;
  font-stretch: normal; font-display: swap;
  src: url('../assets/fonts/ibmplexsans-400-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 500;
  font-stretch: normal; font-display: swap;
  src: url('../assets/fonts/ibmplexsans-500-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 600;
  font-stretch: normal; font-display: swap;
  src: url('../assets/fonts/ibmplexsans-600-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 700;
  font-stretch: normal; font-display: swap;
  src: url('../assets/fonts/ibmplexsans-700-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* Fraunces and Atkinson shipped WITHOUT a latin-ext face until 31. 8. 2026 evening. Measured in
   the woff2 themselves: their latin subsets carry 222 / 219 codepoints and none of them is
   c-caron, s-caron, z-caron, l-acute, r-acute, d-caron, t-caron, l-caron or n-caron. The brand
   wordmark and every Fraunces headline therefore dropped mid-word into the system serif on
   "Dnešná produkcia" — silently, because a missing glyph is a fallback, not an error. Both files
   are static instances of the fontsource variable latin-ext subset at the weight named. */
@font-face {
  font-family: 'Fraunces';
  font-style: normal;
  font-weight: 600; font-display: swap;
  src: url('../assets/fonts/fraunces-600-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Fraunces';
  font-style: normal;
  font-weight: 700; font-display: swap;
  src: url('../assets/fonts/fraunces-700-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Atkinson Hyperlegible Next';
  font-style: normal;
  font-weight: 400; font-display: swap;
  src: url('../assets/fonts/atkinson-400-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Atkinson Hyperlegible Next';
  font-style: normal;
  font-weight: 700; font-display: swap;
  src: url('../assets/fonts/atkinson-700-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
:root{
    /* Tells the browser/OS this page is always dark, regardless of the device's own light/
       dark setting — without this, some mobile browsers render native form controls
       (textareas especially) with their own light-mode chrome on top of our dark CSS, which
       can produce literally invisible text (dark text color inherited, but a light native
       background underneath). This was the cause of Working Time's day-note textarea being
       unreadable while typing. */
    color-scheme: dark;
    --bg: #111110;
    --paper: #191918;
    --paper-raised: #222221;
    --ink: #EEEEEC;
    --ink-dim: #B5B3AD;
    --ink-faint: rgba(181,179,173,0.6);
    --rule: #3B3A37;
    --copper: #0BD8B6;
    --copper-dim: rgba(11,216,182,0.4);
    --sage: #FFC53D;
    --shadow: 0 8px 28px rgba(0,0,0,0.45);
    /* Visual v2 (Richard, 31. 8. 2026) — Radix-style names from the style-guide image, aliased
       onto the tokens above rather than duplicated, so the sand/teal look and the existing
       --bg/--paper cascade never drift apart. sand1/sand2/light/teal11 track theme flips
       (dark <-> :root[data-theme="light"]); teal9/amber/red/ok-green are the FILL swatches and
       are the same in both themes, which is why each one also has a *-text partner below. */
    --sand1: var(--bg);
    --sand2: var(--paper);
    --sand-rule: var(--rule);
    --light: var(--ink);
    --teal9: #12A594;
    --teal11: var(--copper);
    --amber: #FFC53D;
    --red: #E5484D;
    --ok-green: #30A46C;
    /* ZADANIE §2.5: the fill and the TEXT of a status are not the same colour, and the text one
       flips with the theme while the fill does not. White on #12A594 is 3.07 : 1 and white on
       #30A46C is 3.16 : 1 — both below AA — so a status word is drawn with its *-text token,
       never with the fill. On #FFC53D the readable colour is plain black (13.3 : 1). */
    --amber-text: #FFCA16;
    --red-text: #FF9592;
    --ok-green-text: #3DD68C;
    --on-amber: #21201C;
    /* Text on the teal fill. The guide gives this exact value for the wordmark on a teal
       surface (§2.4a) and it is the same problem for a button label: white is 3.07 : 1.
       Fixed in both themes, because the fill is fixed in both themes. */
    --on-teal: #04231F;
    /* Brand navy. The only place the retired 0A1A2F value is still legitimate: it is the ERP top
       bar and the brand's dark surface, not a UI colour. */
    --brand-dark: #0A1A2F;
    /* Card hairline. §2.6: cards are the paper colour with a 1px hairline, no shadow and no
       gradient. Dark reuses --rule; light gets its own warmer line. */
    --card-rule: var(--rule);
    /* Type roles (style guide "Kitchen OS for wet hands"): brand/logo, headings, UI+tables,
       data readouts. Self-hosted @font-face above (CSP font-src 'self' forbids Google's CDN);
       every stack ends in the pre-existing system fallback so nothing regresses if a woff2
       404s. */
    --font-brand: 'Fraunces', Georgia, "Iowan Old Style", "Palatino Linotype", serif;
    --font-heading: 'Bricolage Grotesque', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    --font-ui: 'IBM Plex Sans', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    --font-data: 'Atkinson Hyperlegible Next', "SF Mono", "Menlo", "Consolas", monospace;
  }
  /* Light mode (bod 10, 16.7.) — same tokens, re-defined. --ink reuses the brand navy itself as
     body text (continuity with the dark theme's identity instead of a generic gray), --copper
     is deepened from the neon dark-mode teal since bright mint text is nearly unreadable on a
     white page — the same hue, just legible at light-background contrast. */
  :root[data-theme="light"]{
    /* "Sand statt Slate" (style-guide image 5, 31. 8. 2026): warm off-white sand instead of the
       cool blue-white this theme shipped with — same idea as dark's navy-to-charcoal move, kept
       to the one existing light theme rather than a third variant. */
    --bg: #FDFDFC;
    --paper: #FFFFFF;
    --paper-raised: #F1F0EF;
    --ink: #21201C;
    --ink-dim: #63635E;
    --ink-faint: rgba(33,32,28,0.5);
    --rule: #DAD9D6;
    --copper: #008573;
    --copper-dim: rgba(0,133,115,0.22);
    --sage: #AB6400;
    --shadow: 0 8px 28px rgba(17,17,16,0.12);
    --sand1: var(--bg);
    /* "Podklad sekcie" is its own surface in the guide, one warm step below the app background
       and one above a card. In dark it happens to equal --paper; in light it does not, so it
       stops being an alias here. */
    --sand2: #F9F9F8;
    --sand-rule: var(--rule);
    --light: var(--ink);
    /* Fills do NOT flip with the theme (guide table: "Znacka - plocha" is #12a594 in both
       columns). Only the *-text partners below flip. */
    --teal9: #12A594;
    --teal11: var(--copper);
    --amber: #FFC53D;
    --red: #E5484D;
    --ok-green: #30A46C;
    --amber-text: #AB6400;
    --red-text: #CE2C31;
    --ok-green-text: #218358;
    --on-amber: #21201C;
    /* Text on the teal fill. The guide gives this exact value for the wordmark on a teal
       surface (§2.4a) and it is the same problem for a button label: white is 3.07 : 1.
       Fixed in both themes, because the fill is fixed in both themes. */
    --on-teal: #04231F;
    --card-rule: #ECEAE7;
  }
  *{box-sizing:border-box; -webkit-tap-highlight-color: transparent;}
  /* touch-action:manipulation disables iOS Safari's DOUBLE-TAP-to-zoom (which fits the tapped
     element to the screen width — an accidental double-tap on a recipe-shelf tile made the whole
     grid look zoomed to 2 big columns on the phone while the Mac was fine; Richard, 22.7.). Pinch
     zoom stays enabled, so accessibility zoom is untouched. */
  html,body{margin:0; padding:0; height:100%; max-width:100vw; overflow-x:hidden; touch-action:manipulation;}
  /* Room to scroll PAST the floating bubbles (Richard, 25.7.: "bubliny na hľadať, pridať a
     feedback zakrývajú tlačidlá hide section a delete section — musí sa dať skrolovať nad
     bubliny"). The FABs are position:fixed at bottom:22–24px and are ~56px tall, so they cover
     roughly the last 90px of every screen — and whatever happens to sit last (Hide section,
     Delete section, the deleted-items block) was simply unreachable. <body> is the real
     scroller here, so this one rule covers every view. On body only, never html, so the fixed
     bubbles themselves are not pushed down with it. */
  body{padding-bottom:calc(104px + env(safe-area-inset-bottom, 0px));}
  /* Standing rule (Richard, 25.7.): "všade kde niečo píšem a vytváram/hľadám chcem mať
     tlačidlo hľadať/vytvoriť v tom istom riadku ako píšem". The primary action belongs ON the
     row you are typing in — not under an icon grid you have to scroll past first. One class so
     every such row looks and behaves the same. */
  .inline-name-row{display:flex; gap:8px; align-items:center;}
  .inline-name-row .form-field{flex:1; min-width:0; margin:0;}
  .inline-name-row .save-btn{flex:none; white-space:nowrap; margin:0;}
  /* Printing has no floating buttons — don't leave a blank strip at the end of the page. */
  @media print{ body{padding-bottom:0;} }
  body{
    background: var(--bg);
    background-image: radial-gradient(ellipse 900px 500px at 50% -120px, rgba(11,216,182,0.06), transparent);
    color: var(--ink);
    font-family: var(--font-ui);
    overscroll-behavior-y: contain;
    -webkit-font-smoothing: antialiased;
  }
  ::selection{ background: var(--teal9); color: #111110; }
  button, input, select, textarea{ font: inherit; }
  button{ cursor:pointer; transition: background-color 0.15s ease, border-color 0.15s ease, opacity 0.15s ease, transform 0.1s ease; }
  a{ transition: color 0.15s ease; }
  input, select, textarea{ transition: border-color 0.15s ease, box-shadow 0.15s ease; }
  input:focus-visible, select:focus-visible, textarea:focus-visible, button:focus-visible, a:focus-visible{
    outline: none;
    box-shadow: 0 0 0 2px var(--bg), 0 0 0 4px var(--copper);
    border-radius: 4px;
  }
  .display{
    font-family: var(--font-brand);
  }
  .mono{
    font-family: var(--font-data);
  }

  /* ---------- Login (and the coming-soon wall, which shares its shell) ---------- */
  /* The wall was added 15.7. in 2aa2a2f with its own .box and no rule of its own, and .box
     inherits nothing from #loginView. So for three weeks every new visitor got it with 0px
     padding, no card and no centering — text running edge to edge on a phone. Found by opening
     app.sautero.ch, not by comparing a SHA: the selector was valid the whole time, so no static
     check could ever see it. Both screens share ONE rule now, so a third screen added to this
     pair cannot silently drift out of it again. Measured at 393px: card 345px wide, 24px each
     side, vertically centred, identical padding and radius to the login card. */
  #loginView, #comingSoonView{
    min-height: 100vh;
    display:flex; align-items:center; justify-content:center;
    padding: 24px;
  }
  #loginView .box, #comingSoonView .box{
    width:100%; max-width:380px;
    background: var(--paper);
    border: 1px solid var(--rule);
    border-radius: 20px;
    padding: 40px 32px 32px 32px;
    box-shadow: var(--shadow);
    animation: loginRise 0.5s cubic-bezier(.2,.8,.2,1);
  }
  @keyframes loginRise{ from{ opacity:0; transform:translateY(10px); } to{ opacity:1; transform:translateY(0); } }

  /* ---------- The consent and onboarding gates ---------- */
  /* Same root cause as the coming-soon wall, found 4.8. while writing guard 88: each of these
     carries a .box and no rule ever matched it, so all seven rendered at 0px padding with the
     heading, the body text and the buttons flush against both edges of the phone. Measured three
     ways before touching anything — computed style, CSS source, screenshot — because seven at
     once is the kind of claim that is worth being wrong about only once.

     They deliberately do NOT join the login pair above. Richard's call, 4.8.: padding only, no
     card. Their content SCROLLS (the privacy gate is a long consent text), and `max-width:380px`
     with `align-items:center` would crop it — the safe fix is the gutter, nothing else. So no
     flex, no min-height, no max-width here: the box stays full width and the page keeps
     scrolling exactly as it does today. */
  #teamGateView, #privacyGateView, #confidentialityGateView, #myProfileGateView,
  #passwordGateView, #accountTypeGateView, #nameKitchenGateView{
    padding: 24px;
  }

  .login-mark{ font-size:34px; text-align:center; margin-bottom:14px; }

  /* The chef on the coming-soon wall — Richard, 4.8.: "pridaj tam animáciu kuchára ako kraja
     alebo prehadzuje panvicu". Drawn here rather than loaded: an SVG in the markup costs one
     request fewer than a file and cannot 404 on the one page a stranger sees first. About 1 kB.
     The wall only — the sign-in card keeps its still emoji, because movement beside a password
     field is a distraction, and that was Richard's choice when asked.
     One pivot at the shoulder: the sleeve, the pan and the handle swing as a single group, which
     is what makes it read as a toss instead of a wobbling object. */
  .chef-mark{ display:block; margin:0 auto 14px; width:66px; height:66px; }
  .chef-arm{ transform-origin:32px 40px; animation:chefToss 2s ease-in-out infinite; }
  .chef-bit{ animation:chefBit 2s ease-in-out infinite; }
  .chef-bit:nth-of-type(2){ animation-delay:.06s; }
  .chef-bit:nth-of-type(3){ animation-delay:.12s; }
  @keyframes chefToss{
     0%,40%{ transform:rotate(0deg); }
    50%   { transform:rotate(-24deg); }
    60%   { transform:rotate(9deg); }
    70%,100%{ transform:rotate(0deg); }
  }
  @keyframes chefBit{
     0%,42%{ transform:translate(0,0);      opacity:0; }
    47%   { transform:translate(1px,-6px);  opacity:1; }
    54%   { transform:translate(4px,-17px); opacity:1; }
    62%   { transform:translate(8px,-6px);  opacity:1; }
    68%   { transform:translate(9px,0);     opacity:1; }
    74%,100%{ transform:translate(9px,0);   opacity:0; }
  }
  /* A moving picture is not worth a headache. Frozen mid-toss it still reads as a kitchen. */
  @media (prefers-reduced-motion: reduce){
    .chef-arm, .chef-bit{ animation:none; }
    .chef-arm{ transform:rotate(-12deg); }
    .chef-bit{ opacity:1; }
  }

  #loginView .kicker, #loginView h1{ text-align:center; }
  #loginView h1.title{ margin-bottom:6px; }
  .login-tagline{
    text-align:center; color:var(--ink-dim); font-size:14px;
    margin: 0 0 30px 0; line-height:1.5;
  }
  .form-status{ font-size:12px; color:var(--sage); min-height:16px; margin: 8px 0 4px 0; }
  .form-status.error{ color:#E5484D; }
  .login-hint{ font-size:12px; color:var(--ink-faint); line-height:1.5; margin:6px 0 14px 0; }

  /* ---------- Desktop sign-in: brand panel + post-sign-in intro (Richard, 2. 9. 2026) ---------- */
  /* Built by renderLoginBrandPanel() in js/login.js. Below 1024px nothing changes: the phone
     keeps the card it had, and the loop video is never created there. The panel is sand in BOTH
     themes on purpose — the loop video's own ground is #FAF6E5 (measured from its frames, not
     guessed) and a theme-flipping ground would draw a visible rectangle around the picture.
     The card keeps its selector (#loginView .box — guard 88) and #loginView keeps display:flex
     (JS shows it with 'flex' — guard 89); at desktop the flex row just gets two children. */
  .login-brand{ display:none; }
  @media (min-width: 1024px){
    #loginView{ padding:0; align-items:stretch; }
    #loginView .login-brand{
      display:flex; flex:1 1 55%; min-width:0;
      flex-direction:column; align-items:center; justify-content:center; gap:32px;
      padding:56px 64px;
      background:#FAF6E5; color:#21201C;
    }
    .login-brand-media{ width:min(380px, 44vh); aspect-ratio:4 / 5; }
    .login-brand-video{ display:block; width:100%; height:100%; object-fit:cover; border-radius:28px; }
    .login-brand-copy{ max-width:52ch; text-align:center; }
    #loginView .login-brand .kicker{ color:#067A68; margin-bottom:8px; }
    .login-brand-title{
      font-family:var(--font-heading); font-size:28px; font-weight:600; line-height:1.15;
      margin:0 0 12px; color:#21201C; text-wrap:balance;
    }
    .login-brand-lede{ font-size:15px; line-height:1.6; color:#4A4943; margin:0 0 18px; }
    .login-brand-list{ list-style:none; padding:0; margin:0; display:flex; flex-wrap:wrap; justify-content:center; gap:8px; }
    .login-brand-list li{
      font-family:var(--font-ui); font-size:12.5px; letter-spacing:.04em;
      padding:6px 12px; border:1px solid #D9D2BC; border-radius:999px; color:#21201C;
    }
    #loginView .box{
      flex:1 1 45%; min-width:0; max-width:none;
      border:0; border-radius:0; box-shadow:none;
      display:flex; flex-direction:column; justify-content:center; align-items:center;
      padding:56px 64px;
    }
    #loginView .box > *{ width:100%; max-width:400px; }
  }
  /* The intro overlay never blocks (pointer-events:none) — only Skip takes clicks. Full-bleed
     cover: the film starts on black and ends on near-white, so no ground behind it would match
     both; the picture is the ground. */
  .sautero-intro{
    position:fixed; inset:0; z-index:100000;
    display:flex; align-items:center; justify-content:center;
    background:#000; pointer-events:none;
    opacity:1; transition:opacity .45s ease;
  }
  .sautero-intro video{ width:100%; height:100%; object-fit:cover; }
  .sautero-intro.is-done{ opacity:0; }
  .sautero-intro-skip{
    pointer-events:auto; position:absolute; right:24px; bottom:24px;
    font-family:var(--font-ui); font-size:13px; font-weight:600; letter-spacing:.04em;
    padding:10px 16px; border-radius:999px; border:1px solid rgba(255,255,255,.4);
    background:rgba(0,0,0,.45); color:#FFFFFF; cursor:pointer;
  }
  .sautero-intro-skip:focus-visible{ outline:2px solid #0BD8B6; outline-offset:2px; }
  @media (prefers-reduced-motion: reduce){
    .sautero-intro{ transition:none; }
  }

  /* ---------- Top bar ---------- */
  .topbar{
    position: sticky; top:0; z-index: 10;
    background: var(--bg);
    padding: 22px 18px 12px 18px;
  }
  /* Personal/Company toggle, centered in the top bar on EVERY screen (Richard, 22.7. — "v strede
     a vždy a všade", "sprav to ako pre Apple"). A 3-zone flex row (brand · toggle · icons) with
     the toggle in a flex:1 middle zone that centers it and RESERVES its space — so it can never
     overlap the side content, on any width. The crowded Home bar lost Scan settings + Currency
     (both still in Settings) to give it clean room. */
  .mode-toggle-zone{ flex:1 1 auto; display:flex; justify-content:center; min-width:0; }
  .mode-toggle-center{
    display:inline-flex; align-items:center; gap:5px;
    background: var(--paper-raised, rgba(11,216,182,0.10));
    border:1px solid var(--copper-dim, rgba(11,216,182,0.35));
    color: var(--ink);
    font-family:inherit; font-size:12.5px; font-weight:700; line-height:1; white-space:nowrap;
    padding:7px 14px; border-radius:999px; cursor:pointer;
    transition: background .15s, border-color .15s, transform .1s;
  }
  .mode-toggle-center:hover{ border-color: var(--copper, #0BD8B6); }
  .mode-toggle-center:active{ transform: scale(0.94); }
  .kicker{
    color: var(--copper);
    font-size: 11px;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    margin: 0 0 4px 0;
    font-weight: 600;
    /* German is one word where English is two. "Kitchen Notebook" wraps at its space and fits
       the 96px brand slot; "Küchennotizbuch" is a single 15-letter word that measured 145px and
       was simply cut off on Home — found by the I18N gate on 28.7., not by a person.
       <html lang> already follows the chosen language (applyTranslations sets de-CH), so the
       browser can hyphenate it properly instead of us shortening a brand word. */
    hyphens: auto;
    overflow-wrap: anywhere;   /* last resort only — the German string carries a soft hyphen at
                                  its compound seam, so it breaks as KÜCHEN-/NOTIZBUCH. Without
                                  it, headless Chromium (no hyphenation dictionary) broke the
                                  word blindly as KÜCHENNO-/TIZBUCH, which reads wrong to a
                                  German speaker even though it fits. */
  }
  .sync-status{
    font-size: 11px;
    letter-spacing: 0.04em;
    color: var(--ink-dim);
    opacity: 0;
    transition: opacity 0.2s;
    display:flex; align-items:center; gap:5px;
  }
  .sync-status::before{ content:''; width:5px; height:5px; border-radius:50%; background:currentColor; }
  .sync-status.saving, .sync-status.offline{ opacity: 1; }
  .sync-status.saved{ opacity: 0; }
  .sync-status.offline{ color: #E5484D; }
  h1.title{
    /* Visual v2 correction (Richard, 31.8.2026 — "looks exactly like before"): this rule used
       to be the app's only big-title style, so it defaulted to Fraunces for everything. The
       style guide reserves Fraunces for the literal "Sautero" wordmark only; every other
       h1.title (Check List, Recipes, Ingredients, HACCP, Settings, ...) is a section HEADING
       and belongs in Bricolage Grotesque. The brand-mark override right below restores Fraunces
       on the four real logo instances (login/coming-soon/home-topbar/team-gate). */
    font-family: var(--font-heading);
    font-size: 30px;
    margin: 0 0 16px 0;
    font-weight: 500;
    letter-spacing: -0.015em;
  }
  h1.title.brand-mark{ font-family: var(--font-brand); }
  .search-wrap{
    display:flex;
    align-items:center;
    gap:8px;
    background: var(--paper-raised);
    border: 1px solid var(--rule);
    border-radius: 12px;
    padding: 11px 14px;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
  }
  .search-wrap:focus-within{ border-color: var(--copper-dim); box-shadow: 0 0 0 3px var(--copper-wash, rgba(11,216,182,0.12)); }
  .search-wrap svg{ flex:none; opacity:0.55; }
  .search-action-btn{
    flex:none;
    background: var(--teal9);
    color: #111110;
    border: none;
    padding: 7px 12px;
    border-radius: 8px;
    font-family: inherit;
    font-size: 12.5px;
    font-weight: 600;
    white-space: nowrap;
  }
  #search{
    flex:1;
    background:none; border:none; outline:none;
    color: var(--ink);
    font-size: 16px;
    font-family: inherit;
  }
  #search::placeholder{ color: var(--ink-dim); }
  .nav-row{ display:flex; gap:8px; margin-top:12px; }
  .ingredients-nav-btn{
    display:flex; flex-direction:column; align-items:center; gap:5px;
    flex:1;
    background: var(--paper-raised); border: 1px solid var(--rule);
    color: var(--ink-dim);
    font-family: inherit; font-size: 11.5px; font-weight:500;
    padding: 12px 6px 10px 6px; border-radius: 12px;
    text-align:center;
  }
  .ingredients-nav-btn svg{ display:none; }
  .ingredients-nav-btn:active{ background: var(--surface-raised, var(--paper-raised)); transform: scale(0.97); }
  .ingredients-nav-btn:hover{ border-color: var(--copper-dim); color: var(--ink); }
  .nav-icon{ font-size: 18px; line-height:1; }

  /* ---------- Home dashboard ---------- */
  .home-grid{
    display:grid; grid-template-columns: repeat(3, 1fr);
    gap: 10px;
    padding: 10px 18px 40px 18px;
  }
  .home-tile{
    display:flex; flex-direction:column; align-items:center; justify-content:center; gap:6px;
    aspect-ratio: 1;
    /* min-width:0 is REQUIRED with aspect-ratio in a grid (Richard, 22.7. — the bug he finally
       pinned to "only in the classic theme"): a grid item defaults to min-width:auto = its
       min-content width, and iOS Safari transfers the aspect-ratio through that minimum, so the
       square tiles refused to shrink to the 1fr track and the whole Recipes shelf grid collapsed
       from 3 columns to 2 big ones (with the 3rd column — Company Recipes — pushed off-screen) on
       the phone, while desktop was fine. (The redesign-ui theme, removed 3.8.2026, escaped this
       because its tiles set overflow:hidden, which also forces the automatic minimum to 0 — it hid
       the symptom rather than fixing it.) Chromium doesn't reproduce it; iOS Safari does. */
    min-width: 0;
    background: var(--paper-raised);
    border: 1px solid var(--rule);
    border-radius: 14px;
    color: var(--ink);
    font-family: inherit; font-size: 12px; font-weight:600;
    padding: 6px;
  }
  /* Bez translateY (Richard, 5. 9. 2026 v noci: „pri hýbaní myšou niektoré vignety gličujú"): dlaždica
     sa pod kurzorom posunula o 2 px, kurzor na spodnej hrane z nej vypadol, hover skončil, dlaždica
     sa vrátila pod kurzor, hover začal — blikanie. Zvýraznenie ostáva na farbe a tieni, ktoré tvar nemenia. */
  .home-tile:hover{ border-color: var(--teal9); background: var(--surface, var(--paper-raised)); box-shadow: 0 6px 24px rgba(18,165,148,0.18); }
  .home-tile:active{ transform: scale(0.97); }
  /* ---------- Check List tiles (Richard, 4.8.2026) ---------- */
  /* Reuses .home-grid/.home-tile so the tiles are the same object the main menu uses — same size,
     same radius, same press behaviour — rather than a second look-alike that drifts. The only new
     thing is a tile that spans the whole row, because Richard asked for To do list as one wide
     vignette across the first three positions.

     `grid-column: 1 / -1` spans every column WHATEVER the count is, so it stays one row on the
     phone's 3 columns and on the desktop's 4 (media query at 400) without a second rule. And it
     drops aspect-ratio:1 — a full-width square would be 350px tall on a phone and push everything
     else off the screen. */
  .cl-tile-wide{
    grid-column: 1 / -1;
    aspect-ratio: auto;
    flex-direction: row; justify-content: space-between;
    /* Richard, 4.8. 00:11 "o 20% vačšiu - potiahnuť ju dolu ale vrch je dobree", then 00:24
       "kludne by som to ešte o 13% natiahol dolu". Both increments go on the BOTTOM only — the top
       padding stays at 14px, so the distance from the header never moves from the one he approved.
       Measured: 92 → 110 (+20%) → 124 (+13%). */
    padding: 14px 16px 46px 16px;
    align-items: flex-start;
    gap: 12px;
  }
  .cl-tile-wide .cl-wide-left{ display:flex; align-items:center; gap:12px; min-width:0; }
  /* Richard, 5.8. 00:46: "tú ikonu v baneri treba zvačšiť tak aby bola asi o 80% vačšia … najlepšie
     keby tam ten štvorec okolo nej nebol vobec". The frame is dropped and the glyph itself grows
     44px -> 62px, which is +41% on the glyph but +80% on what the eye reads as the icon, because
     the 62px box that used to surround it is gone and the picture now fills that space instead of
     sitting inside it. Height stays inside the banner: 62px glyph in a tile whose content box is
     124 - 14 - 46 = 64px. */
  .cl-tile-wide .home-tile-icon{
    background: none; border: none; border-radius: 0;
    font-size: 62px; width: auto; height: auto;
  }
  .cl-tile-wide .cl-wide-label{ font-size:14px; font-weight:700; letter-spacing:.01em; }
  /* The count is the reason this tile exists, so it is the biggest thing on it. */
  /* Richard, 5.8. 00:49: "číslo na pravo chcem mať v rovnakej velkosti ako aj čas obe centrované
     na stred a o kusok viac vlavo". So the count drops from 24px to the 15px the stopwatch row
     uses, both blocks centre on the same axis, and the pair moves in from the edge. */
  .cl-count{ font-family: var(--font-data); font-size:15px; font-weight:400; line-height:1; }
  /* Right-hand column: the count, and under it the stopwatch (Richard, 4.8. 00:12). The slot is
     drawn even though the duration is empty — the icon says WHERE the time will be, and a dash
     says honestly that there is none yet. Inventing a figure to fill it would look identical to
     a measured one, and the per-item minutes are empty in all 58 production rows. */
  /* Richard, 00:24: "čas a počet úloh by som dal takto pod seba" — on his screenshot the two are
     boxed one above the other. The stopwatch was squeezed against the count and barely readable,
     so the gap doubles and the row gets its own size rather than shrinking into the corner. */
  .cl-wide-right{ display:flex; flex-direction:column; align-items:center; gap:12px;
                  margin-right:14px; }
  /* Richard, 00:29: "chcem aby tie stopky bolli v strede toho obdlžnika" — centred UNDER the
     count rather than pushed to the tile's right edge, so the two read as one stacked block. */
  .cl-time{ display:flex; align-items:center; justify-content:center; align-self:center;
            gap:6px; color:var(--ink-dim); font-size:15px; font-weight:600; line-height:1; }
  .cl-time svg{ opacity:.85; }
  .cl-count-total{ color: var(--ink-dim); font-size:15px; }
  .cl-count-none{ color: var(--ink-dim); font-size:13px; font-weight:600; }

  /* The three section books get their own colour (Richard: "každá z tých troch dlaždíc bude mať
     inú farbu knihy"), carried on a left edge rather than a full fill — a solid coloured tile
     beside two neutral ones reads as an alert, and none of these is one. The same three values
     are what the To do list rows will use to show where a line came from, so they live in one
     place and are referenced, never retyped. */
  /* Richard, 5.8. 00:19: "tie dalšie dlaždice sprav všetky centrované na stred". .home-tile is
     already centred both ways; this makes the label behave when it wraps to two lines, which the
     German ones do. */
  #checkListTileGrid .home-tile:not(.cl-tile-wide){ text-align:center; }
  #checkListTileGrid .home-tile:not(.cl-tile-wide) > span{ max-width:100%; }
  /* Richard, 5.8. 01:01-01:04: "tie tri ikony musia byt v riadku" and then "nie kade tade".
     Two separate problems, one fix each.

     · .home-grid widens to 4 columns above 400px, which pushed Check the order up beside the
       three books and split them across rows. This grid stays at 3 on every screen.
     · everything else on the page was a different width — the quick picks ran edge to edge while
       the tiles sat in a centred 640px column and the projects in another. Three blocks, three
       alignments, which is what "kade tade" means. They now share one column and one edge. */
  #checkListTileGrid, #checkListTopTileGrid{
    grid-template-columns: repeat(3, 1fr) !important;
  }
  .cl-tile-book{ border-left: 4px solid var(--rule); }
  .cl-book-service{ border-left-color: #0BD8B6; }
  .cl-book-stations{ border-left-color: #FF9E7A; }
  .cl-book-plates{ border-left-color: #B39DFF; }
  .cl-book-bqt{ border-left-color: #FFD166; }
  .cl-tile-sub{ color: var(--ink-dim); font-size:11px; font-weight:600; }

  /* Three quick picks across the very top (Richard, 5.8., with a marked-up screenshot showing
     them above the To do list tile): "listy ktoré si viem sám zvoliť (kliknem a hodí ma to do
     konkretneho check listu na nejaké jedlo)". Per person and per project, kept in localStorage —
     these are somebody's own shortcuts, not kitchen data, and they must not travel to a colleague
     who never chose them. An empty slot shows a + and is still a button, so the row never looks
     broken before it has been set up. */
  .home-tile-icon{
    font-size: 44px; line-height:1;
    width:62px; height:62px; flex:none;
    display:flex; align-items:center; justify-content:center;
    background: var(--paper); border:1px solid var(--rule); border-radius:10px;
  }
  /* German and Slovak build single words longer than a third of a phone screen, and a tile is
     exactly that wide. "Schädlingsbekämpfung" on the HACCP hub was clipped mid-word the moment
     those tiles started translating (30.7.2026 — seen in a browser at 375px, not inferred: the
     catalogue and every guard were green while the label read "Schädlingsbekämpfun"). A label
     must break INSIDE a word rather than run off the edge. hyphens:auto puts the break where
     German hyphenation allows it, and <html lang> already carries de-CH (applyTranslations sets
     it) so the browser knows which rules to use. Written theme-agnostically on purpose: the
     redesign-ui theme (removed 3.8.2026) hid the overflow instead of wrapping it, which is the
     same clipping with the evidence removed. */
  .home-tile-label{
    max-width:100%; text-align:center; line-height:1.2;
    overflow-wrap:anywhere; hyphens:auto;
  }
  @media (min-width: 560px){
    .home-grid{ grid-template-columns: repeat(4, 1fr); max-width:640px; margin:0 auto; }
  }

  /* ---------- Schedule: week nav + grid ---------- */
  .date-nav{ display:flex; align-items:center; justify-content:space-between; gap:8px; }
  .week-label{ font-family:var(--font-data); font-size:13px; color:var(--ink-dim); text-align:center; flex:1; }
  .schedule-grid-wrap{ overflow-x:auto; padding: 4px 0 8px 0; -webkit-overflow-scrolling:touch; }
  .schedule-day-roster{ padding: 8px 16px 4px; }
  .schedule-day-roster .desktop-erp-schedule.is-static{
    cursor: default; width: 100%; text-align: left;
  }
  .schedule-day-roster .desktop-erp-schedule.is-static:hover{ border-color: var(--rule); }
  table.schedule-grid{ border-collapse:collapse; width:100%; min-width:640px; }
  table.schedule-grid th, table.schedule-grid td{ border-bottom:1px solid var(--rule); padding:0; }
  table.schedule-grid thead th{
    font-size:11px; text-transform:uppercase; letter-spacing:0.05em; color:var(--ink-faint);
    font-weight:600; padding:8px 6px; text-align:center; background:var(--bg);
    position:sticky; top:0; z-index:2;
  }
  table.schedule-grid thead th.day-selected{
    color: var(--teal11, #0BD8B6);
    background: color-mix(in srgb, var(--teal11, #0BD8B6) 12%, transparent);
  }
  table.schedule-grid thead th .day-pick{
    display:block; width:100%; background:transparent; border:0; color:inherit;
    font: inherit; cursor:pointer; padding:4px 2px; border-radius:6px;
  }
  table.schedule-grid thead th .day-pick:focus-visible{
    outline:2px solid var(--teal11, #0BD8B6); outline-offset:1px;
  }
  table.schedule-grid thead th.name-col{ text-align:left; padding-left:18px; }
  table.schedule-grid .name-col{
    position:sticky; left:0; z-index:1;
    background:var(--bg);
    padding: 10px 12px 10px 18px;
    font-size:13.5px; white-space:nowrap;
    box-shadow: 1px 0 0 var(--rule);
  }
  table.schedule-grid .section-row td{
    background: var(--paper-raised);
    font-size:11px; text-transform:uppercase; letter-spacing:0.1em; color:var(--sage); font-weight:600;
    padding: 8px 12px 8px 18px;
  }
  table.schedule-grid .cell-btn{
    width:100%; min-width:60px; height:44px;
    background:none; border:none; border-left:1px solid var(--rule);
    color: var(--ink); font-family:var(--font-data); font-size:12px; font-weight:600;
    cursor:pointer;
  }
  table.schedule-grid .cell-btn:hover{ background: var(--paper-raised); }
  table.schedule-grid .cell-btn.absence{ color: var(--ink-faint); font-weight:400; }
  table.schedule-grid .cell-btn.empty{ color: var(--rule); }
  .staff-add-row{ display:flex; gap:8px; margin-top:10px; }
  .staff-add-row input{ flex:1; }

  /* ---------- Fridge temperature ---------- */
  .fridge-card{
    display:flex; align-items:center; gap:14px;
    background: var(--paper-raised); border:1px solid var(--rule); border-radius:12px;
    padding:14px 16px; margin-bottom:12px; cursor:pointer;
    transition: border-color 0.15s ease;
  }
  .fridge-card:hover{ border-color: var(--copper-dim); }
  .fridge-status-dot{ width:12px; height:12px; border-radius:50%; flex:none; }
  .fridge-status-dot.ok{ background: var(--sage); }
  .fridge-status-dot.warn{ background: #E5484D; }
  .fridge-status-dot.none{ background: var(--rule); }
  .fridge-card .info{ flex:1; }
  .fridge-card .name{ font-size:15.5px; font-weight:600; }
  .fridge-card .meta{ font-size:12.5px; color:var(--ink-dim); margin-top:2px; }
  .fridge-card .reading{ font-family:var(--font-data); font-size:20px; color:var(--copper); font-weight:600; }
  .fridge-log-row{ display:flex; justify-content:space-between; padding:10px 0; border-bottom:1px solid var(--rule); font-size:14px; }
  .fridge-log-row .temp{ font-family:var(--font-data); color:var(--copper); font-weight:600; }

  /* ---------- Working Time (check-in/out) ---------- */
  .wt-card{
    background: var(--paper-raised); border:1px solid var(--rule); border-radius:12px;
    padding:16px; margin-bottom:14px;
  }
  .wt-elapsed{ font-family:var(--font-data); font-size:36px; font-weight:700; color: var(--copper); text-align:center; }
  .wt-status-live .meta{ text-align:center; color:var(--ink-dim); font-size:13px; margin-top:4px; margin-bottom:14px; }
  .wt-summary-grid{ display:flex; gap:10px; margin-top:8px; }
  .wt-stat{ flex:1; text-align:center; background: var(--paper); border:1px solid var(--rule); border-radius:10px; padding:12px 6px; }
  .wt-stat-num{ font-family:var(--font-data); font-size:22px; font-weight:700; color: var(--copper); }
  .wt-stat-label{ font-size:10.5px; color:var(--ink-dim); text-transform:uppercase; letter-spacing:0.04em; margin-top:4px; }
  .wt-settings-row{ display:flex; align-items:center; justify-content:space-between; gap:10px; padding:10px 0; border-bottom:1px solid var(--rule); }
  .wt-settings-row:last-of-type{ border-bottom:none; }
  .wt-vacation-days{ font-size:15px; font-weight:600; margin-top:2px; }
  .wt-vacation-countdown{ font-size:12px; color:var(--copper); font-weight:600; margin-top:2px; }
  .wt-sticky-top{ position:sticky; top:0; z-index:10; background:var(--bg); border-bottom:1px solid var(--rule); padding-top:0; }
  .wt-chart-legend{ display:flex; gap:12px; flex-wrap:wrap; font-size:11px; color:var(--ink-dim); margin:2px 0 12px 0; }
  .wt-dot{ display:inline-block; width:8px; height:8px; border-radius:2px; margin-right:4px; vertical-align:middle; }
  .wt-dot-actual{ background:var(--teal9); }
  .wt-dot-forecast{ background:var(--sage); opacity:0.55; }
  .wt-dot-absence{ background:var(--rule); }
  .wt-dot-none{ background-image: repeating-linear-gradient(45deg, var(--ink-dim) 0, var(--ink-dim) 1px, transparent 1px, transparent 4px); }
  .wt-chart-scroll{ display:flex; gap:4px; overflow-x:auto; padding-bottom:6px; }
  .wt-bar-col{ flex:none; width:22px; display:flex; flex-direction:column; align-items:center; }
  .wt-bar-col.wt-bar-today .wt-bar-label{ color: var(--copper); font-weight:700; }
  .wt-bar-track{ width:100%; height:110px; background: var(--paper); border-radius:4px; display:flex; align-items:flex-end; overflow:hidden; border:1px solid var(--rule); }
  .wt-bar{ width:100%; border-radius:3px 3px 0 0; min-height:2px; }
  .wt-bar-actual{ background: var(--teal9); }
  .wt-bar-overtime{ background:#E5484D; } /* hours beyond 8/day — stacked on top of the teal bar (17.7.) */
  .wt-bar-forecast{ background: var(--sage); opacity:0.6; }
  .wt-bar-absence{ background: var(--rule); }
  .wt-bar-none{ background-image: repeating-linear-gradient(45deg, var(--rule) 0, var(--rule) 2px, transparent 2px, transparent 5px); }
  .wt-bar-label{ font-size:9.5px; color:var(--ink-dim); margin-top:3px; }
  .wt-advisory-point{ display:flex; align-items:flex-start; gap:9px; padding:9px 0; border-bottom:1px solid var(--rule); font-size:13.5px; line-height:1.4; }
  .wt-advisory-point:last-child{ border-bottom:none; }
  .wt-check-btn{
    flex:none; width:22px; height:22px; margin-top:1px; border-radius:6px;
    border:1.5px solid var(--rule); background:var(--paper);
    display:flex; align-items:center; justify-content:center;
    color:#fff; font-size:13px; font-weight:700; line-height:1;
  }
  .wt-check-btn.checked{ background: var(--sage); border-color: var(--sage); }
  .wt-point-done{ text-decoration:line-through; color:var(--ink-dim); }

  /* Compact, tappable summary card in the sticky top bar — opens the monthly pie-chart view */
  #workingTimeSummaryCard{ padding:8px 10px; cursor:pointer; }
  #workingTimeSummaryCard .section-label{ padding:0 0 3px 0; border-top:none; margin-top:0; font-size:9px; display:flex; align-items:center; justify-content:space-between; }
  #workingTimeSummaryCard .wt-summary-grid{ gap:6px; margin-top:0; }
  #workingTimeSummaryCard .wt-stat{ padding:5px 3px; border-radius:7px; }
  #workingTimeSummaryCard .wt-stat-num{ font-size:14px; }
  #workingTimeSummaryCard .wt-stat-label{ font-size:8px; margin-top:1px; }

  /* Working Time — monthly pie-chart history view */
  .wt-pie-grid{ display:grid; grid-template-columns:repeat(3,1fr); gap:16px 10px; padding:6px 0 20px 0; }
  .wt-pie-cell{ display:flex; flex-direction:column; align-items:center; gap:6px; cursor:pointer; }
  .wt-pie{ width:66px; height:66px; border-radius:50%; border:1px solid var(--rule); }
  .wt-pie-empty{ background: repeating-linear-gradient(45deg, var(--paper) 0, var(--paper) 4px, var(--paper-raised) 4px, var(--paper-raised) 8px); }
  .wt-pie-label{ font-size:12px; font-weight:700; }
  .wt-pie-sub{ font-size:10px; color:var(--ink-dim); text-align:center; }
  .wt-bar-weekday{ font-size:8.5px; color:var(--ink-faint, var(--ink-dim)); }
  .fridge-log-row .temp.warn{ color:#E5484D; }

  /* ---------- Bottom action sheet (used by the ingredient info panel) ---------- */
  .sheet-overlay{
    position:fixed; inset:0;
    background: rgba(10,9,7,0.6);
    display:none;
    align-items:flex-end;
    justify-content:center;
    z-index: 50;
  }
  .sheet-overlay.open{ display:flex; }
  .sheet{
    background: var(--paper-raised);
    border: 1px solid var(--rule);
    border-bottom: none;
    border-radius: 18px 18px 0 0;
    padding: 10px 20px calc(20px + env(safe-area-inset-bottom, 0px)) 20px;
    width: 100%;
    max-width: 480px;
    box-sizing: border-box;
    max-height: 80vh;
    overflow-y: auto;
  }
  /* Three-menus proposals sheet: ~1.2× the default 480px so dish lines and Print / Chose
     buttons breathe on desktop ERP (Richard, 1.9.2026). Mobile stays full-bleed under 576px. */
  #menuOptionsOverlay .sheet{ max-width: 576px; }
  /* Reorder sheets list every Home/Settings tile, so they get tall. Make the LIST itself the
     scroll area and keep the "Done" button pinned at the bottom — so on a short window (Richard,
     20.7. — Mac / Proton) you can always scroll to the last icons AND reach Done, whatever the
     window height. Scoped to the two reorder overlays only; every other sheet is untouched. */
  #homeReorderOverlay .sheet, #settingsReorderOverlay .sheet{ display:flex; flex-direction:column; overflow:hidden; }
  #homeReorderOverlay .sheet > :not(#homeReorderList),
  #settingsReorderOverlay .sheet > :not(#settingsReorderList){ flex:0 0 auto; }
  #homeReorderList, #settingsReorderList{ flex:1 1 auto; min-height:0; overflow-y:auto; -webkit-overflow-scrolling:touch; }
  .sheet-handle{
    width: 36px; height: 4px; border-radius: 999px;
    background: var(--rule);
    margin: 8px auto 14px auto;
  }
  .sheet-cancel{
    width:100%;
    margin-top:14px;
    background:none;
    border:1px solid var(--rule);
    color: var(--ink-dim);
    padding:12px;
    border-radius:10px;
    font-family:inherit;
    font-size:14px;
  }
  .ingredient-info-title{ font-family: var(--font-heading); font-size:19px; margin:4px 0 4px 0; }
  .ingredient-info-row{ margin: 12px 0; }
  .ingredient-info-row .label{ font-size:11px; text-transform:uppercase; letter-spacing:0.08em; color:var(--sage); margin-bottom:3px; }
  .ingredient-info-row .value{ font-size:14px; line-height:1.5; }

  /* ---------- Add-choice sheet options + API key settings ---------- */
  .sheet-option{
    display:flex; align-items:center; gap:14px;
    width:100%;
    background:none; border:none;
    border-top: 1px solid var(--rule);
    padding: 14px 4px;
    color: var(--ink);
    text-align:left;
    font-family: inherit;
  }
  .sheet-option:first-of-type{ border-top:none; }
  .sheet-option svg{ flex:none; color: var(--copper); }
  .sheet-option-title{ font-size:15px; font-weight:600; }
  .sheet-option-sub{ font-size:12px; color:var(--ink-dim); margin-top:2px; }
  .sheet-title{ font-family: var(--font-heading); font-size:19px; margin:4px 0 10px 0; }
  .sheet-text{ font-size:13px; color:var(--ink-dim); line-height:1.5; margin:0 0 16px 0; }
  .sheet-link{ color:var(--copper); }
  .sheet-row{ display:flex; gap:10px; margin-bottom: 8px; }
  .sheet-row .save-btn, .sheet-row .danger-btn{ flex:1; margin-top:0; text-align:center; }
  .sheet-status{ font-size:12px; color:var(--sage); min-height:16px; margin: 8px 0 4px 0; }

  /* ---------- Photo scan progress overlay ---------- */
  .scan-overlay{
    position:fixed; inset:0;
    background: rgba(23,21,18,0.94);
    display:none;
    align-items:center; justify-content:center;
    z-index: 60;
  }
  .scan-overlay.open{ display:flex; }
  .scan-box{ text-align:center; padding: 20px; max-width:320px; }
  /* The grey ring that used to spin here was retired on 31.7. — every scan shows the boiling
     pot now, the same one saving already used. The rule is gone rather than left orphaned so
     nobody re-attaches a second waiting language by accident. */

  /* COOKING ANIMATION (Richard, 29.7.: "chcem aby tá animácia čakania bola v podobe animácie
     výroby jedla, napríklad vriaca polievka"). A generic spinner says "the computer is busy";
     a pot coming to the boil says "your food is being put away", which is the same wait wearing
     the language of the kitchen it is standing in.

     Built from divs, not a GIF or Lottie: this app has no build step and no asset pipeline, and
     a spinner that costs a network request is a spinner that hangs on the kitchen wifi — the one
     place it must not. Roughly 1 kB of CSS, no request, scales to any size.

     prefers-reduced-motion is honoured. Motion sickness is a real condition, and a cook who has
     it should get a still pot rather than nothing at all. */
  .cook-anim{ width:104px; height:92px; margin:0 auto 18px; position:relative; }
  .cook-anim .pot{
    position:absolute; left:14px; bottom:6px; width:76px; height:40px;
    background:linear-gradient(180deg, var(--rule) 0%, rgba(0,0,0,.35) 100%);
    border-radius:5px 5px 14px 14px;
  }
  /* The soup itself — the lip of liquid across the top of the pot, gently rocking. */
  .cook-anim .soup{
    position:absolute; left:18px; bottom:40px; width:68px; height:8px;
    background:var(--teal9); border-radius:50%;
    animation:cook-rock 2.2s ease-in-out infinite;
  }
  .cook-anim .handle{
    position:absolute; bottom:30px; width:12px; height:7px;
    border:2px solid var(--rule); border-radius:3px;
  }
  .cook-anim .handle.l{ left:4px; }
  .cook-anim .handle.r{ right:4px; }
  .cook-anim .bubble{
    position:absolute; bottom:40px; width:7px; height:7px; border-radius:50%;
    background:var(--teal9); opacity:0;
    animation:cook-bubble 1.9s ease-in infinite;
  }
  .cook-anim .bubble.b1{ left:32px; animation-delay:0s; }
  .cook-anim .bubble.b2{ left:50px; animation-delay:.55s; width:9px; height:9px; }
  .cook-anim .bubble.b3{ left:66px; animation-delay:1.1s; }
  /* Steam reads as steam only because it drifts sideways while it rises and fades. */
  .cook-anim .steam{
    position:absolute; bottom:52px; width:5px; height:16px; border-radius:3px;
    background:linear-gradient(180deg, rgba(255,255,255,.55), rgba(255,255,255,0));
    opacity:0; animation:cook-steam 2.6s ease-out infinite;
  }
  .cook-anim .steam.s1{ left:34px; animation-delay:.2s; }
  .cook-anim .steam.s2{ left:50px; animation-delay:1.0s; height:20px; }
  .cook-anim .steam.s3{ left:66px; animation-delay:1.7s; }
  @keyframes cook-rock{ 0%,100%{ transform:scaleY(1); } 50%{ transform:scaleY(1.5); } }
  @keyframes cook-bubble{
    0%{ opacity:0; transform:translateY(0) scale(.4); }
    25%{ opacity:.95; }
    100%{ opacity:0; transform:translateY(-16px) scale(1.15); }
  }
  @keyframes cook-steam{
    0%{ opacity:0; transform:translateY(0) translateX(0) scaleY(.6); }
    30%{ opacity:.75; }
    100%{ opacity:0; transform:translateY(-30px) translateX(7px) scaleY(1.25); }
  }
  @media (prefers-reduced-motion: reduce){
    .cook-anim .soup, .cook-anim .bubble, .cook-anim .steam{ animation:none; }
    .cook-anim .bubble, .cook-anim .steam{ opacity:.5; }
  }
  /* In-sheet wait (Chef's Assistant "save chat as recipe"): same pot + teal bar/dots,
     centred under the sheet title so a cook sees motion without a full-screen scrim. */
  .sheet-wait{ text-align:center; padding:4px 0 8px; }
  .sheet-wait .cook-anim{ margin:4px auto 10px; transform:scale(.9); transform-origin:top center; }
  .sheet-wait-bar{
    height:3px; border-radius:99px; overflow:hidden;
    background:var(--copper-wash, rgba(11,216,182,0.15)); margin:0 auto 12px; max-width:220px;
  }
  .sheet-wait-bar > span{
    display:block; height:100%; width:34%;
    background:var(--copper);
    animation:sheet-wait-bar 1.4s ease-in-out infinite;
  }
  .sheet-wait-msg{ display:inline-flex; align-items:center; flex-wrap:wrap; gap:6px; justify-content:center; margin-bottom:8px; }
  .sheet-wait-dots{ display:inline-flex; gap:4px; vertical-align:middle; }
  .sheet-wait-dots span{
    width:6px; height:6px; border-radius:50%; background:var(--copper);
    animation:sheet-wait-dot 1.2s ease-in-out infinite;
  }
  .sheet-wait-dots span:nth-child(2){ animation-delay:.2s; }
  .sheet-wait-dots span:nth-child(3){ animation-delay:.4s; }
  @keyframes sheet-wait-bar{
    0%{ transform:translateX(-110%); }
    100%{ transform:translateX(320%); }
  }
  @keyframes sheet-wait-dot{
    0%,80%,100%{ opacity:.25; transform:translateY(0); }
    40%{ opacity:1; transform:translateY(-3px); }
  }
  @media (prefers-reduced-motion: reduce){
    .sheet-wait-bar > span, .sheet-wait-dots span{ animation:none; opacity:.7; }
  }
  .scan-status{ font-size:14px; color:var(--ink-dim); }
  .scan-error{ font-size:13px; color:#E5484D; margin-top:14px; }

  /* ---------- Task rows (Mise en Place) ---------- */
  .task-row{ padding:14px 18px; border-bottom:1px solid var(--rule); }
  .task-row.status-finish .task-text{ text-decoration:line-through; color:var(--ink-dim); }
  .task-row-top{ display:flex; align-items:flex-start; justify-content:space-between; gap:10px; }
  .task-note{ color: var(--copper); font-size:13px; margin-top:3px; }
  .task-status-group{ display:flex; gap:6px; margin-top:9px; }
  .task-col-header{
    display:flex; justify-content:space-between;
    padding: 10px 18px 6px 18px;
    font-size: 11px; text-transform:uppercase; letter-spacing:0.1em;
    color: var(--ink-dim);
    border-bottom: 1px solid var(--rule);
  }
  .task-status-btn{
    flex:none;
    font-family: inherit; font-size: 11px; font-weight:700; letter-spacing:0.04em;
    padding: 6px 10px; border-radius: 6px;
    border: 1px solid var(--rule); background: var(--paper);
    color: var(--ink-dim);
    opacity: 0.85;
  }
  /* STANDARD (Richard, 15.7., "nie prvýkrát riešime"): a selected filter must be unmissable —
     full teal fill + dark text, never just an opacity change. Applies to every filter chip in
     the app; Check List's status buttons keep their own semantic colors via the more-specific
     .status-* rules below, which is intentional. */
  .task-status-btn.active{
    opacity: 1;
    background: var(--teal9); border-color: var(--copper);
    color: #111110; font-weight: 800;
  }
  .icon-choice-grid{ display:grid; grid-template-columns:repeat(6,1fr); gap:6px; margin:8px 0; }
  .icon-choice-btn{
    font-size:22px; padding:8px 0; border-radius:8px;
    border:1px solid var(--rule); background: var(--paper);
    cursor:pointer;
  }
  .icon-choice-btn.active{ border-color: var(--copper); background: rgba(11,216,182,0.16); }
  /* #E5484D is the FILL red; as text it reads 3.91 : 1 on white paper. --red-text is the same
     red moved to a text weight per theme (8.35 dark, 5.21 light). White on the 32 % tint is
     1.54 : 1 in the light theme — the tint composites to #F7C4C6 — where --ink gives 10.61. */
  .task-status-btn.status-todo{ color:var(--red-text); border-color:#7a3b34; }
  .task-status-btn.status-todo.active{ color:var(--ink); border-color:#E5484D; background: rgba(229,72,77,0.32); }
  .task-status-btn.status-check{ color: var(--copper); border-color: var(--copper-dim); }
  .task-status-btn.status-check.active{ background: rgba(11,216,182,0.15); }
  .task-status-btn.status-finish{ color: var(--sage); border-color: var(--sage); }
  .task-status-btn.status-finish.active{ background: rgba(255,197,61,0.15); }
  .task-status-btn.status-dontdo{ color: var(--ink-dim); border-color: var(--rule); }
  .task-status-btn.status-dontdo.active{ color: var(--ink); border-color: var(--ink-dim); background: rgba(236,229,216,0.14); }
  /* Two states (mandate 2. 9. 2026): make wears the todo colours, done the finish colours. */
  .task-status-btn.status-make{ color:var(--red-text); border-color:#7a3b34; }
  .task-status-btn.status-make.active{ color:var(--ink); border-color:#E5484D; background: rgba(229,72,77,0.32); }
  .task-status-btn.status-done{ color: var(--sage); border-color: var(--sage); }
  .task-status-btn.status-done.active{ background: rgba(255,197,61,0.15); }
  .task-priority-badge{
    flex:none; width:22px; height:22px; border-radius:50%;
    display:flex; align-items:center; justify-content:center;
    font-family:var(--font-data); font-size:11px; font-weight:600;
    border: 1px solid var(--rule);
  }
  .priority-1, .priority-2{ color:var(--red-text); border-color:#7a3b34; }
  .priority-3{ color: var(--copper); border-color: var(--copper-dim); }
  .priority-4, .priority-5{ color: var(--sage); border-color: var(--sage); }

  /* ---------- Prep sheet (dish-grouped, e.g. Saucier) ---------- */
  .prep-section-summary{
    display:flex; gap:8px; flex-wrap:wrap;
    padding: 10px 18px;
    font-size: 13px; color: var(--ink);
  }
  .prep-section-summary b{ color: var(--ink); font-family:var(--font-data); }
  .prep-section-summary > span:not(.prep-filter-toggle){ padding:5px 10px; }
  .prep-filter-toggle{
    cursor:pointer; padding:5px 10px; border-radius:999px;
    border:1px solid var(--rule); background: var(--paper-raised, var(--paper));
  }
  .prep-filter-toggle::after{ content:' ▾'; font-size:9px; opacity:0.6; }
  .prep-filter-toggle:active{ transform: scale(0.97); }
  .prep-filter-toggle:hover{ border-color: var(--copper-dim); }
  .prep-filter-toggle.active{ border-color: var(--copper); background: var(--teal9); color: #111110; font-weight: 800; }
  .prep-filter-toggle.active::after{ content:' ▴'; }
  .prep-flag{ margin-left:6px; font-size:14px; }
  /* Deliberately loud — Richard's own words, "do očí bijúca výstraha" (an eye-catching
     warning) — so a checked item that's also tracked under another dish/section doesn't get
     missed. Gold, not red: this isn't a danger/delete signal, just "pay attention, shared
     ingredient elsewhere." */
  .prep-duplicate-badge{
    font-family:inherit; font-size:11px; font-weight:700;
    background: rgba(255,197,61,0.2); border:1.5px solid #FFC53D; color:#FFC53D;
    border-radius:999px; padding:4px 10px; cursor:pointer;
  }
  .prep-duplicate-badge:active{ background: rgba(255,197,61,0.35); }
  .prep-item-dish{ color: var(--ink); opacity:0.75; font-weight:400; font-size:12.5px; }
  .prep-dish-card{ border-bottom: 1px solid var(--rule); padding: 4px 0 12px 0; }
  .prep-hidden-row{ opacity: 0.55; }
  .prep-dish-header{
    display:flex; align-items:baseline; justify-content:space-between; gap:10px; flex-wrap:wrap;
    padding: 14px 18px 10px 18px;
    background: rgba(11,216,182,0.16);
    border-left: 3px solid var(--copper);
  }
  .prep-dish-name{ font-family: Georgia, serif; font-size: 17px; color: var(--copper); }
  .prep-dish-header-right{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
  .prep-dish-price{ font-family:var(--font-data); font-size:13px; color: var(--copper); }
  .prep-dish-total-time{ font-family:var(--font-data); font-size:13px; color: var(--ink); }
  .prep-item-table{ padding: 4px 18px 0 18px; }
  /* Exactly 3 lines per item, all in the same monospace font as the on-hand/priority
     fields (Richard's explicit request, with his own hand-drawn row sketch as reference):
     line 1 = name + flag + on-hand + priority; line 2 = status + time + timer;
     line 3 = note + order/hide/delete. */
  .prep-item-row{
    padding: 10px 6px;
    border-top: 1px solid var(--rule);
    background: rgba(255,197,61,0.12);
    font-family:var(--font-data);
  }
  .prep-line1{ display:flex; align-items:center; flex-wrap:wrap; gap:6px 10px; margin-bottom:5px; }
  .prep-item-name{ font-size: 14px; font-weight:700; color: var(--sage); overflow-wrap:anywhere; }
  /* On-hand, priority, and the time-per-task badge always stay together on their own row right
     below the name — never split apart, regardless of how long the name (+ dish suffix) gets.
     nowrap + horizontal scroll as a safety valve rather than ever letting these three wrap
     onto separate ragged lines like they used to. */
  .prep-line1b{ display:flex; align-items:center; flex-wrap:nowrap; gap:10px; margin-bottom:7px; overflow-x:auto; }
  /* ONE row of controls under the name (31.7., Richard's photo): Done ▾ · Order · Print ·
     Notes · priority ▾ · ⋮. It scrolls sideways rather than wrapping, because a row that
     re-wraps as labels change length is exactly how the old four-line version grew. */
  .prep-line-one{
    display:flex; align-items:center; flex-wrap:nowrap; gap:4px;
    overflow-x:auto; -webkit-overflow-scrolling:touch; padding-bottom:2px;
  }
  /* Tightened until all six controls fit a 375 px phone WITHOUT sideways scrolling — measured
     in a real browser, not estimated. The first attempt kept the buttons' normal padding and
     their emoji, and priority + ⋮ fell off the right edge: 407 px of controls in a 307 px line. */
  /* The three WORD buttons may shrink; the action, the priority and ⋮ never do. German and
     Slovak labels run ~20 % longer than English ("Bestellen", "Objednať", "Poznámka") and pushed
     the row to 371 px inside a 307 px line — which would have hidden ⋮ off the right edge in the
     two languages this kitchen actually runs in. Measured in a browser at 375 px in all three.
     A truncated word the cook can still tap beats a control they cannot reach at all. */
  .prep-line-one .task-status-btn{
    flex:0 1 auto; min-width:0; padding:6px 7px; font-size:11.5px;
    white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
  }
  .prep-line-one .prep-priority{ flex:none; width:44px; padding:5px 2px; text-align:center; font-size:13px; }
  .prep-line-one .prep-act-btn,
  .prep-line-one .prep-dots{ flex:none; }
  .prep-act-btn{ font-weight:700; }
  .prep-dots{ padding:6px 6px; }
  .prep-field-inline{ display:flex; align-items:center; gap:5px; flex:none; }
  .prep-field-label{
    font-size:10px; text-transform:uppercase; letter-spacing:0.06em;
    color: var(--ink); opacity:0.8; font-weight:600;
  }
  .prep-input{
    min-width:0;
    background: var(--paper-raised, var(--paper)); border: 1px solid var(--rule); border-radius:6px;
    color: var(--ink); font-family:inherit; font-size:16px; font-weight:600;
    padding: 5px 6px;
  }
  .prep-priority{ padding:5px 2px; }
  .prep-time-remaining{
    margin-left:auto; padding:5px 10px; border-radius:999px;
    font-family:var(--font-data); border:1px solid var(--copper-dim);
    color: var(--copper); background: rgba(11,216,182,0.1);
  }
  .prep-section-name{ display:inline-flex; align-items:center; gap:5px; font-weight:700; color: var(--ink); cursor:pointer; }
  /* Section name + Visibility + time-remaining live on their own row below the
     to-do/check/finish/don't-do chips. If the name is long enough that Visibility and the
     time pill don't both fit next to it, that pair wraps as a unit (never splitting from each
     other) onto its own centered line — instead of each one landing on a separate ragged line. */
  .prep-summary-row2{ flex-basis:100%; display:flex; flex-wrap:wrap; align-items:center; justify-content:center; gap:8px; }
  .prep-summary-meta{ display:flex; align-items:center; gap:8px; flex:none; }
  .prep-summary-meta .prep-time-remaining{ margin-left:0; }
  .prep-line2{ display:flex; gap:6px; flex-wrap:wrap; align-items:center; }
  .prep-status-group{ display:flex; gap:6px; flex-wrap:wrap; align-items:center; }
  .prep-line3{ display:flex; align-items:center; gap:6px; flex-wrap:wrap; margin-top:7px; }
  .prep-line3 .prep-note{ flex-basis:100%; order:-1; }
  .task-status-btn.status-danger{ color:var(--red-text); border-color:#7a3b34; }
  .task-status-btn.status-danger:active{ background: rgba(229,72,77,0.2); }
  .prep-note{ flex:1; min-width:0; font-family:inherit; font-weight:400; font-style:italic; }
  .prep-item-clock{
    font-family:inherit; font-size:12px; font-weight:600;
    color: var(--copper); margin-left:4px;
    background:none; border:none; padding:0; cursor:pointer;
  }
  .prep-item-clock:active{ opacity:0.7; }
  /* Timer button reuses the exact same look as TO DO/CHECK/FINISH/DON'T DO — Richard's
     explicit request, "rovnaký dizajn ako tlačítka to do check finish a dont do". */
  .task-status-btn.status-timer{
    display:flex; align-items:center; gap:5px; color: var(--sage); border-color: var(--sage-dim, var(--rule));
    font-size:13px; padding:7px 12px;
  }
  .task-status-btn.status-timer.active{ color:#fff; border-color:#E5484D; background: rgba(229,72,77,0.32); }
  .prep-timer-live{ font-variant-numeric: tabular-nums; }
  @media (max-width: 420px){
    /* Font-size stays 16px even here — anything smaller makes iOS Safari auto-zoom the whole
       page on focus, which is the exact "have to zoom back out to reach Home" bug reported. */
    .prep-input{ padding:5px 4px; }
  }

  /* ---------- Chef's Assistant (chat) ---------- */
  /* 100dvh (not 100vh) so the input bar stays above the on-screen keyboard on mobile —
     100vh is measured before the keyboard opens and doesn't shrink with it, which was
     leaving the input half-covered when the keyboard appeared. */
  /* A focused full-screen chat: fixed to the viewport so its input bar is always visible on open
     (the old normal-flow 100dvh + window.scrollTo(0,0) no-op left the field below the fold), and
     JS keeps its height synced to window.visualViewport so the on-screen keyboard can never cover
     the input (Richard, 22.7.). Its own topbar has Home, so the floating nav + feedback bubble are
     hidden while it's open (below) — that overlapping bubble was the reported "second comment icon". */
  /* The one full-screen fixed view: body padding cannot move it, so it consumes the demo
     chrome's height itself or the chrome covers its topbar. */
  #chefAssistantView{ position:fixed; top:var(--demo-chrome-h, 0px); left:0; right:0; height:calc(100dvh - var(--demo-chrome-h, 0px)); display:flex; flex-direction:column; background:var(--bg); z-index:36; overflow-x:hidden; }
  body.chef-chat-open .floating-nav,
  body.chef-chat-open .global-feedback-btn{ display:none !important; }
  .chef-chat-messages{
    flex:1; overflow-y:auto; overflow-x:hidden;
    padding: 8px 18px 18px 18px;
    display:flex; flex-direction:column; gap:12px;
  }
  .chef-credit-line{ font-size:12px; opacity:.72; text-align:center; padding:2px 0 0; }
  .chef-msg{
    max-width: 82%;
    padding: 11px 14px;
    border-radius: 14px;
    font-size: 14.5px; line-height:1.5;
    white-space: pre-wrap; overflow-wrap:anywhere;
  }
  .chef-msg.user{
    align-self:flex-end;
    background: var(--copper-dim); color:var(--copper);
    border-bottom-right-radius:4px;
  }
  .chef-msg.assistant{
    align-self:flex-start;
    background: var(--paper-raised, var(--paper)); border:1px solid var(--rule); color:var(--ink);
    border-bottom-left-radius:4px;
  }
  .chef-msg.assistant.pending{ color:var(--ink-dim); font-style:italic; }
  .chef-chat-input-bar{
    display:flex; gap:10px; align-items:flex-end;
    padding: 12px 18px calc(14px + env(safe-area-inset-bottom)) 18px;
    border-top: 1px solid var(--rule);
    background: var(--bg);
  }
  .chef-chat-input{
    flex:1; min-width:0; resize:none; max-height:120px;
    background: var(--paper-raised, var(--paper)); border:1px solid var(--rule); border-radius:12px;
    color: var(--ink); font-family:inherit; font-size:16px;   /* >=16px so iOS Safari never auto-zooms on focus (below) */
    padding: 10px 14px;
  }
  .chef-chat-send{
    flex:none; padding:10px 18px; border-radius:12px; border:none;
    background: var(--teal9); color:#111110; font-weight:700; font-size:14px;
  }
  .chef-chat-send:disabled{ opacity:0.5; }
  .chef-empty-state{ color:var(--ink-dim); font-size:14px; padding:18px; text-align:center; }
  .chef-save-row{ display:flex; flex-wrap:wrap; gap:4px 14px; align-self:flex-start; margin-top:-6px; }
  .chef-save-row .chef-save-recipe{ margin-top:0; }
  .chef-save-menu{ color: var(--sage); }
  .chef-save-recipe{ align-self:flex-start; margin-top:-6px; background:none; border:none; color:var(--copper); font-size:12.5px; font-weight:600; cursor:pointer; padding:2px; }

  /* ---------- Quick-add checklist (Mise en Place / Order List) ---------- */
  .qa-row{
    display:flex; align-items:center; gap:12px;
    padding: 12px 14px; margin-bottom: 8px;
    border-radius: 8px;
    border: 1px solid var(--rule);
    background: rgba(255,197,61,0.10);
  }
  .qa-row.selected{ background: rgba(217,58,58,var(--qa-alpha, 0.2)); border-color: rgba(217,58,58,0.4); }
  .qa-checkbox{
    flex:none; width:24px; height:24px; border-radius:6px;
    border: 1.5px solid var(--rule); background: var(--paper);
    display:flex; align-items:center; justify-content:center;
  }
  .qa-row.selected .qa-checkbox{ background:#E5484D; border-color:#E5484D; }
  .qa-checkbox.checked{ background:#E5484D; border-color:#E5484D; color:#fff; font-weight:700; font-size:13px; }
  .qa-info{ flex:1; min-width:0; }
  .qa-info .name{ font-size:15px; font-weight:500; }
  .qa-info .meta{ font-size:12.5px; color:var(--ink-dim); margin-top:2px; }
  .qa-row.order-checked{ background: rgba(11,216,182,0.16); border-color: var(--copper-dim); }
  .qa-row.order-checked .qa-checkbox{ background: var(--teal9); border-color: var(--copper); }
  .qa-qty-input{
    flex:none; width:64px;
    background: var(--paper); border: 1px solid var(--rule); border-radius:6px;
    color: var(--ink); font-family:var(--font-data); font-size:16px; padding:5px 6px;
  }
  .qa-priority{
    flex:none; width:60px;
    background: var(--paper); border: 1px solid var(--rule); border-radius:6px;
    color: var(--ink); font-family:inherit; font-size:16px; padding:5px;
  }
  .cuisine-badge{
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    padding: 2px 7px;
    border-radius: 999px;
    background: rgba(11,216,182,0.12);
    border: 1px solid var(--copper-dim);
    color: var(--copper);
    flex: none;
    margin-left: 6px;
  }
  .ingredient-row .price{
    font-family: var(--font-data);
    color: var(--copper);
    font-size: 14px;
    flex: none;
  }

  /* ---------- Category filter chips ---------- */
  .chips{
    display:flex; gap:8px;
    overflow-x:auto;
    padding: 12px 18px 4px 18px;
    scrollbar-width:none;
  }
  .chips::-webkit-scrollbar{display:none;}

  /* ---------- Mise en Place sticky header ----------
     Topbar + station chips + (when a prep sheet is open) the status summary all live inside
     one sticky block, so there is exactly one solid edge where the header ends and the
     scrolling list begins — no gaps or see-through seams between separately-stuck pieces. */
  .sticky-header{
    position: sticky; top:0; z-index: 10;
    background: var(--bg);
    border-bottom: 1px solid var(--rule);
  }
  .sticky-header .topbar{ position:static; padding-bottom:8px; }
  .sticky-header .chips{
    position:static; padding: 4px 18px 12px 18px;
    flex-wrap:wrap; overflow-x:visible;
  }
  .sticky-header .prep-section-summary{ border-bottom:none; padding-top:6px; }
  /* Check List's header is ONLY Home + the to-do/check/finish/don't-do + time row, always
     pinned, in every section, from the moment it renders — no scroll needed, no delay. The
     full section grid (icons, overload badges, + New Section, Visibility) moved into the ☰
     picker sheet instead of living inline, since it was too tall to stay glued to the top
     without eating most of the screen. Richard asked for this three times in a row — it must
     not regress. */
  #tasksView .sticky-header{ position: sticky; top:0; z-index:10; }
  #tasksView .topbar{ padding-bottom:2px; }

  .back-to-top-btn{
    position: fixed; left:20px; bottom:24px;
    width:46px; height:46px; border-radius:50%;
    background: var(--paper-raised, var(--paper)); color: var(--ink);
    border:1px solid var(--rule);
    display:none; align-items:center; justify-content:center;
    box-shadow: 0 6px 20px rgba(0,0,0,0.4);
    z-index:20; cursor:pointer;
  }
  .back-to-top-btn.visible{ display:flex; }

  /* ---------- Station tiles (Mise en Place) — same visual language as the Home grid ---------- */
  .station-tile{
    position:relative;
    display:flex; flex-direction:column; align-items:center; justify-content:center; gap:3px;
    width: 78px; flex:none;
    background: var(--paper-raised); border:1px solid var(--rule); border-radius:14px;
    color: var(--ink); font-family:inherit;
    padding: 10px 4px 8px 4px;
  }
  .station-tile.active{ border-color: var(--copper); background: rgba(11,216,182,0.14); }
  .station-tile:active{ transform: scale(0.96); }
  .station-tile-icon{ font-size:22px; line-height:1; }
  .station-tile-label{ font-size:11px; font-weight:600; text-align:center; line-height:1.2; }
  .station-tile-stat{ font-size:10px; color:var(--ink-dim); font-family:var(--font-data); }
  .station-tile-warning{
    position:absolute; top:-7px; right:-6px; font-size:15px;
    filter: drop-shadow(0 1px 2px rgba(0,0,0,0.5));
  }
  .all-station-strip{ padding: 10px 18px 4px 18px; border-bottom:1px solid var(--rule); margin-bottom:6px; }
  .all-station-strip-row{
    width:100%; display:flex; align-items:center; gap:10px;
    background:none; border:none; border-top:1px solid var(--rule);
    color: var(--ink); font-family:inherit; padding:10px 2px; text-align:left;
  }
  .all-station-strip-row:first-child{ border-top:none; }
  .all-station-strip-name{ flex:1; font-size:14.5px; font-weight:600; }
  .chip{
    flex:none;
    padding: 8px 15px;
    border-radius: 999px;
    border: 1px solid var(--rule);
    color: var(--ink-dim);
    font-size: 13px;
    font-weight: 500;
    white-space:nowrap;
    background: var(--paper);
    transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease, transform 0.1s ease;
  }
  .chip:active{ transform: scale(0.96); }
  .chip.active{
    background: var(--teal9);
    border-color: var(--copper);
    color: #111110;
    font-weight: 800;
  }

  /* ---------- List ---------- */
  #listView{ display:none; padding: 6px 0 40px 0; }
  .section-label{
    padding: 20px 18px 8px 18px;
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    color: var(--ink-dim);
    border-top: 1px solid var(--rule);
    margin-top: 4px;
  }
  .section-label:first-child{ border-top:none; }
  /* Same visual language as a Check List item row (.prep-item-row): monospace, soft sage
     background wash, top divider instead of a floating card — Richard's request to unify the
     two screens' design, using Check List (already "the way I imagined") as the reference. */
  .recipe-row{
    display:flex;
    align-items:center;
    gap:14px;
    padding: 12px 18px;
    border-top: 1px solid var(--rule);
    background: rgba(255,197,61,0.12);
    font-family: var(--font-data);
    cursor:pointer;
    transition: background-color 0.15s ease;
  }
  .recipe-row:hover{ background: rgba(255,197,61,0.2); }
  .recipe-row:active{ background: rgba(255,197,61,0.2); }
  .recipe-row .chevron{ transition: transform 0.15s ease; }
  .recipe-row:hover .chevron{ transform: translateX(2px); color: var(--copper); }
  .recipe-row .idx{
    font-size: 12px;
    color: var(--copper);
    width: 22px;
    flex:none;
  }
  .recipe-row .info, .info{ flex:1; min-width:0; }
  .recipe-row .name{
    font-size: 15px;
    font-weight: 700;
    color: var(--sage);
  }
  .recipe-row .meta{
    font-size: 12.5px;
    color: var(--ink-dim);
    margin-top: 3px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .recipe-row .chevron{ flex:none; color: var(--ink-dim); }
  .row-comments{ flex:none; display:flex; align-items:center; gap:3px; color: var(--copper); font-size:12px; font-weight:800; }
  .thumb{
    flex:none;
    width:48px; height:48px;
    border-radius:8px;
    object-fit:cover;
    border:1px solid var(--rule);
  }
  .hero{
    width:100%;
    height:200px;
    object-fit:cover;
    border-radius:10px;
    margin-bottom:16px;
    border:1px solid var(--rule);
  }
  .empty-state{
    padding: 70px 24px;
    text-align:center;
    color: var(--ink-dim);
    font-size: 14.5px;
    line-height:1.6;
    max-width: 34ch;
    margin: 0 auto;
  }

  /* ---------- Detail view ---------- */
  #detailView{ display:none; }
  .detail-bar{
    position: sticky; top:0; z-index:10;
    background: var(--bg);
    border-bottom: 1px solid var(--rule);
    padding: 14px 18px;
    display:flex; align-items:center; gap:10px;
    /* The row must wrap rather than push the page sideways (28.7.). The Ingredient form carries
       Cancel + a rating star + "Scan" + Save, and in German that is 4px too wide at 375px:
       "Speichern" is 104px where "Save" is 60. The page then scrolled sideways and the right
       edge of EVERY screen was cut off — found by the device matrix, in German, on an iPhone
       viewport. English never showed it, which is why it survived this long.
       min-width:0 lets the flex children shrink instead of forcing the row wider than the
       screen; row-gap keeps a wrapped second line from touching the first. */
    flex-wrap: wrap; row-gap: 8px; min-width: 0;
  }
  .detail-bar > *{ min-width: 0; }
  .back-btn{
    display:flex; align-items:center; gap:6px;
    background:none; border:none;
    color: var(--copper);
    font-size: 15px;
    font-family: inherit;
    padding: 6px 4px;
    cursor:pointer;
    border-radius: 6px;
  }
  .back-btn:hover{ color: #5FFAE3; }
  .detail-content{ padding: 20px 18px 60px 18px; }
  .detail-cat{
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.16em;
    color: var(--copper);
    margin-bottom: 8px;
    font-weight: 600;
  }
  h2.recipe-title{
    font-family: var(--font-heading);
    font-size: clamp(26px, 5vw, 32px);
    font-weight: 500;
    margin: 0 0 8px 0;
    line-height: 1.15;
    letter-spacing: -0.01em;
  }
  .recipe-meta{
    color: var(--ink-dim);
    font-size: 14.5px;
    margin-bottom: 24px;
  }
  .block{ margin-bottom: 28px; }
  .block h3{
    font-size: 12.5px;
    text-transform: uppercase;
    letter-spacing: 0.11em;
    color: var(--sage);
    margin: 0 0 12px 0;
    font-weight: 600;
  }
  table.ing{
    width:100%;
    border-collapse: collapse;
  }
  table.ing tr{ border-bottom: 1px solid var(--rule); }
  table.ing tr:last-child{ border-bottom:none; }
  table.ing td{
    padding: 9px 0;
    font-size: 15px;
    vertical-align: top;
  }
  table.ing td.qty{
    text-align:right;
    font-family: var(--font-data);
    color: var(--copper);
    max-width: 40vw;
    padding-left: 12px;
    font-size: 14px;
  }
  .method-list{
    margin:0; padding:0;
    list-style:none;
    counter-reset: step;
  }
  .method-list li{
    counter-increment: step;
    padding: 4px 0 14px 34px;
    position:relative;
    font-size: 15.5px;
    line-height:1.5;
  }
  .method-list li::before{
    content: counter(step);
    position:absolute;
    left:0; top:2px;
    width:24px; height:24px;
    border-radius:50%;
    background: var(--paper-raised);
    border: 1px solid var(--copper-dim);
    color: var(--copper);
    font-family: var(--font-data);
    font-size: 12px;
    display:flex; align-items:center; justify-content:center;
  }
  .plain-text{ font-size:15px; line-height:1.55; }
  .bullet-list{ margin:0; padding-left: 18px; }
  .bullet-list li{ font-size:15px; line-height:1.6; margin-bottom:4px; }

  /* ---------- Detail bar extras ---------- */
  .bar-spacer{ flex:1; }
  .icon-btn{
    background:none; border:none;
    color: var(--ink-dim);
    padding: 7px;
    cursor:pointer;
    display:flex; align-items:center; justify-content:center;
    border-radius: 9px;
  }
  .icon-btn:hover{ background: var(--paper-raised); color: var(--ink); }
  .icon-btn:active{ background: var(--paper-raised); transform: scale(0.92); }
  .icon-btn.active{ color: var(--copper); }
  .icon-btn.active svg{ fill: var(--copper); }
  .fav-star{
    flex:none;
    background:none; border:none;
    color: var(--ink-dim);
    padding: 4px;
    display:flex; align-items:center; justify-content:center;
  }
  .fav-star.active{ color: var(--copper); }
  .fav-star.active svg{ fill: var(--copper); }

  /* ---------- Cost badge ---------- */
  .cost-block{
    display:flex; flex-wrap:wrap; gap:14px 18px;
    background: var(--paper-raised);
    border: 1px solid var(--rule);
    border-radius: 12px;
    padding: 14px 16px;
    margin-bottom: 22px;
  }
  .cost-item{ flex: 1 1 38%; min-width:80px; }
  .cost-item .label{ font-size:10.5px; text-transform:uppercase; letter-spacing:0.09em; color:var(--ink-dim); font-weight:500; }
  .cost-item .value{ font-family:var(--font-data); font-size:16px; font-weight:600; color:var(--copper); margin-top:3px; }
  .cost-info-btn{
    display:inline-flex; align-items:center; justify-content:center;
    width:16px; height:16px; margin-left:6px;
    border-radius:50%;
    border: 1px solid var(--ink-dim);
    background:none; color:var(--ink-dim);
    font-size:10px; font-family: Georgia, serif; font-style:italic;
    vertical-align:middle; line-height:1;
    padding:0;
  }
  .cost-info-btn:active{ background:var(--paper-raised); }
  .cost-breakdown{
    background: var(--paper-raised);
    border: 1px solid var(--rule);
    border-radius: 8px;
    padding: 10px 12px;
    margin: -8px 0 20px 0;
  }
  .cost-breakdown-row{
    display:flex; justify-content:space-between; gap:10px;
    padding: 6px 0;
    border-bottom: 1px solid var(--rule);
    font-size: 13px;
  }
  .cost-breakdown-row:last-child{ border-bottom:none; }

  /* ---------- Allergen badges ---------- */
  .allergen-row{
    display:flex; flex-wrap:wrap; gap:6px;
    margin-bottom: 20px;
  }
  .allergen-badge{
    font-size: 11.5px;
    padding: 4px 10px;
    border-radius: 999px;
    background: rgba(11,216,182,0.12);
    border: 1px solid var(--copper-dim);
    color: var(--copper);
  }
  .allergen-badge-unknown{
    background: rgba(255,197,61,0.18);
    border-color: var(--sage);
    color: var(--sage);
    font-weight: 800;
  }
  .allergen-unknown-note{
    font-weight: 700;
    color: var(--sage);
    font-style: normal;
  }

  /* ---------- Scaling bar ---------- */
  .scale-bar{
    display:flex; align-items:center; gap:8px;
    flex-wrap: wrap;
    margin-bottom: 18px;
    padding: 10px 12px;
    background: var(--paper-raised);
    border-radius: 8px;
    border: 1px solid var(--rule);
  }
  .scale-label{ font-size:12px; color:var(--ink-dim); flex:none; margin-right:2px; }
  .scale-chip{
    font-family: var(--font-data);
    font-size: 13px;
    padding: 5px 10px;
    border-radius: 6px;
    border: 1px solid var(--rule);
    background: var(--paper);
    color: var(--ink-dim);
    cursor:pointer;
  }
  .scale-chip.active{ background: var(--teal9); border-color: var(--copper); color:#111110; font-weight:800; }
  .scale-chip.custom{ background: var(--teal9); border-color: var(--copper); color:#111110; font-weight:800; cursor:default; }
  .scale-note{
    width:100%;
    font-size: 11px;
    color: var(--ink-dim);
    margin-top: 4px;
    font-style: italic;
  }

  /* ---------- Advanced scaling (by yield / by ingredient) ---------- */
  .scale-advanced{
    margin-bottom: 20px;
    padding: 12px;
    background: var(--paper-raised);
    border-radius: 8px;
    border: 1px solid var(--rule);
  }
  .scale-advanced-title{
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--sage);
    margin-bottom: 10px;
    font-weight: 600;
  }
  .scale-row{
    display:flex;
    align-items:center;
    gap:6px;
    flex-wrap: wrap;
    margin-bottom: 10px;
  }
  .scale-row:last-of-type{ margin-bottom: 0; }
  .scale-row-label{
    font-size: 12.5px;
    color: var(--ink);
    flex: none;
    width: 100%;
    margin-bottom: 4px;
  }
  .scale-input{
    width: 64px;
    background: var(--paper);
    border: 1px solid var(--rule);
    border-radius: 6px;
    color: var(--ink);
    font-family: var(--font-data);
    font-size: 13px;
    padding: 6px 8px;
  }
  .scale-select{
    flex: 1;
    min-width: 120px;
    background: var(--paper);
    border: 1px solid var(--rule);
    border-radius: 6px;
    color: var(--ink);
    font-family: inherit;
    font-size: 13px;
    padding: 6px 8px;
  }
  .scale-arrow{ color: var(--ink-dim); font-size: 13px; flex: none; }
  .scale-apply-btn{
    background: var(--teal9);
    color: #111110;
    border: none;
    font-family: inherit;
    font-size: 12.5px;
    font-weight: 600;
    padding: 7px 12px;
    border-radius: 6px;
    flex: none;
  }
  .scale-apply-btn:active{ background: var(--copper-dim); }
  .scale-result{
    font-size: 12px;
    color: var(--copper);
    margin-top: 6px;
    min-height: 16px;
  }

  /* ---------- Stat badges (yield / time / difficulty) ---------- */
  .stat-row{
    display:flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-bottom: 20px;
  }
  .stat-pill{
    display:flex;
    align-items:center;
    gap: 5px;
    font-size: 12.5px;
    padding: 6px 12px;
    border-radius: 999px;
    background: var(--paper-raised);
    border: 1px solid var(--rule);
    color: var(--ink);
  }
  .stat-pill svg{ flex:none; color: var(--copper); }
  .diff-easy{ color: var(--sage); }
  .diff-medium{ color: var(--copper); }
  .diff-hard{ color: #E5484D; }
  .list-diff-dot{
    display:inline-block;
    width:6px; height:6px;
    border-radius:50%;
    margin-right:5px;
    vertical-align:middle;
  }
  .dot-easy{ background: var(--sage); }
  .dot-medium{ background: var(--teal9); }
  .dot-hard{ background: #E5484D; }

  /* ---------- Notes ---------- */
  .notes-block{ margin-top: 30px; }
  .notes-block h3{
    font-size: 13px; text-transform:uppercase; letter-spacing:0.1em;
    color: var(--sage); margin: 0 0 8px 0; font-weight:600;
  }
  #notesArea{
    width:100%;
    min-height: 80px;
    background: var(--paper-raised);
    border: 1px solid var(--rule);
    border-radius: 8px;
    color: var(--ink);
    font-family: inherit;
    font-size: 14px;
    padding: 10px 12px;
    resize: vertical;
    box-sizing: border-box;
  }
  .notes-status{ font-size:11px; color:var(--ink-dim); margin-top:6px; height:14px; }

  /* ---------- FAB (add recipe) ---------- */
  .fab{
    position: fixed;
    right: 20px; bottom: 24px;
    width: 58px; height: 58px;
    border-radius: 50%;
    background: var(--teal9);
    color: #111110;
    border: none;
    display:flex; align-items:center; justify-content:center;
    box-shadow: 0 6px 20px rgba(0,0,0,0.45), 0 0 0 1px rgba(0,0,0,0.15);
    z-index: 20;
    transition: background-color 0.15s ease, transform 0.15s cubic-bezier(.2,.8,.2,1), box-shadow 0.15s ease;
  }
  .fab:hover{ transform: translateY(-2px); box-shadow: 0 10px 26px rgba(0,0,0,0.5), 0 0 0 1px rgba(0,0,0,0.15); }
  .fab:active{ background: var(--copper-dim); transform: scale(0.94); }
  .fab-search{ right: 90px; }

  /* Floating Back + Home nav (bod 3, 16.7.) — always top-right on every screen except Home.
     Sits above sticky topbars but below sheet overlays, so an open sheet still covers it. */
  /* Back + Home header band (bod, 16.7. večer v3 — per Richard's own mockup): a full-width
     Sautero-branded strip pinned above EVERYTHING on every screen except Home, with the two
     accent buttons inside it. Content and every sticky bar shift down by its height, so
     nothing can ever sit underneath it — the previous floating pill kept overlapping view
     icons no matter how much right-side room was reserved. */
  .floating-nav{
    position:fixed; top:0; left:0; right:0; height:58px;
    /* Richard, 18.7. (real incident): z-index was 900 — ABOVE .sheet-overlay (50) and
       .scan-overlay (60) — so the Home/Back bar stayed clickable through any open sheet/scan
       dialog. He tapped what looked like Home while an Order dialog was open/closing and got a
       "Delete this whole dish" confirm instead — a stray tap landing on this always-on-top bar
       (or on whatever the page settled into afterward) is the concrete, verified mechanism.
       40 keeps it above per-screen sticky headers (10) for normal navigation, but properly
       covered — and inert — once any modal/sheet is open, same as every other app control. */
    z-index:40;
    display:none; align-items:center; justify-content:space-between;
    padding:0 10px 0 18px;
    background:var(--bg);
    border-bottom:1px solid var(--copper-dim, rgba(11,216,182,0.35));
  }
  .floating-nav .fn-brand{ display:flex; flex-direction:column; line-height:1.15; }
  .floating-nav .fn-brand .fn-kicker{ font-size:10px; letter-spacing:.16em; text-transform:uppercase; color:var(--copper); font-weight:700; }
  .floating-nav .fn-brand .fn-name{ font-family:var(--font-brand); font-weight:700; font-size:17px; color:var(--ink); }
  .floating-nav .fn-buttons{ display:flex; align-items:center; gap:8px; }
  .floating-nav .fn-buttons button{
    background:var(--teal9); border:none; color:#111110; cursor:pointer;
    display:flex; align-items:center; justify-content:center;
    width:44px; height:44px; border-radius:50%;
    box-shadow:0 4px 14px rgba(0,0,0,0.4);
  }
  .floating-nav .fn-buttons button:active{ transform:scale(0.92); }
  /* BODY is this app's scroll container, so sticky `top` offsets already resolve from below
     the body's own padding — padding-top alone shifts content AND re-anchors every sticky bar
     under the band. Explicit top:58px overrides here would double the shift (the "gap + cut
     tiles" bug Richard screenshotted) — deliberately none. */
  body.has-floating-nav{ padding-top:calc(58px + var(--demo-chrome-h, 0px)); }
  /* Home carries no nav band, but the demo chrome is fixed there too and still needs its room.
     Lower specificity than the rule above, so it only applies where the band is absent. */
  body{ padding-top: var(--demo-chrome-h, 0px); }

  /* Global feedback/bug/question button — same button on every screen after login, not
     duplicated into 22 different topbars. Left side so it never collides with the
     right-side .fab/.fab-search "add" buttons that most screens already have. */
  .global-feedback-btn{
    position: fixed;
    left: 16px; bottom: 22px;
    width: 46px; height: 46px;
    border-radius: 50%;
    background: var(--paper-raised, var(--paper));
    color: var(--ink);
    border: 1px solid var(--rule);
    display:none; align-items:center; justify-content:center;
    box-shadow: 0 6px 18px rgba(0,0,0,0.4);
    z-index: 35;
    cursor: pointer;
  }
  /* Richard, 24.7.: "bublina na feedback ma pod sebou kopiu". There is exactly ONE bubble in the
     markup — what sat under it was its own drop shadow: offset 6px down with an 18px blur reads as
     a second dark disc on a dark background. Tightened so it lifts the button without doubling it. */
  .global-feedback-btn{ box-shadow: 0 2px 8px rgba(0,0,0,0.32); }
  .global-feedback-btn:hover{ border-color: var(--accent-dim, var(--copper)); }
  #globalFeedbackMenu{
    display:none; position:fixed; left:16px; bottom:74px; z-index:36;
    background: var(--paper); border:1px solid var(--rule); border-radius:10px;
    box-shadow: var(--shadow); min-width:170px; overflow:hidden;
  }

  /* ---------- Add/Edit form ---------- */
  #formView{ display:none; }
  .save-btn{
    background: var(--teal9);
    color: #111110;
    border: none;
    padding: 9px 18px;
    border-radius: 9px;
    font-family: inherit;
    font-size: 14px;
    font-weight: 600;
    letter-spacing: -0.005em;
  }
  .save-btn:hover{ background: #5FFAE3; }
  .save-btn:active{ background: var(--copper-dim); transform: scale(0.98); }
  .form-label{
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--sage);
    margin: 0 0 8px 0;
    font-weight: 600;
    display:block;
  }
  .form-field{
    width:100%;
    background: var(--paper-raised);
    border: 1px solid var(--rule);
    border-radius: 10px;
    color: var(--ink);
    font-family: inherit;
    font-size: 16px;
    padding: 11px 13px;
    margin-bottom: 18px;
    box-sizing: border-box;
  }
  .form-field:focus{ border-color: var(--copper-dim); outline:none; }
  .form-field::placeholder{ color: var(--ink-faint); }
  /* textareas carry more native OS chrome than plain inputs — belt-and-suspenders on top of
     the color-scheme:dark fix above, forcing the typed-text color explicitly. */
  textarea.form-field{ appearance:none; -webkit-appearance:none; -webkit-text-fill-color: var(--ink); }
  /* iOS Safari auto-zooms into any focused input/textarea/select whose font-size is < 16px and
     frequently never zooms back out — the whole app is then zoomed, so the layout is wider than the
     visible area and everything is cut off on the RIGHT (Richard, 22.7. "strany nesedia" — the chat
     input at 15px was the trigger). Baseline every text control at >=16px; classed inputs that set
     their own size keep it (higher specificity), so no layout shifts — this only lifts bare ones. */
  input, textarea, select{ font-size:16px; }
  .lang-switch{
    background: var(--paper-raised); border: 1px solid var(--rule); border-radius:8px;
    color: var(--ink-dim); font-family: inherit; font-size: 16px;
    padding: 6px 10px;
  }
  #homeView .topbar .lang-switch{ margin-top:10px; }
  select.form-field{
    appearance:none; -webkit-appearance:none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%23a89f8f' stroke-width='2.4'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 12px center;
    padding-right: 34px;
  }
  .row-pair{
    display:flex; gap:8px;
    margin-bottom: 8px;
  }
  .row-pair input{ flex:1; }
  .row-pair input.qty-input{ flex: none; width: 90px; }
  .row-remove{
    flex:none;
    background:none; border:none;
    color: var(--ink-dim);
    width: 36px;
    display:flex; align-items:center; justify-content:center;
  }
  .add-row-btn{
    background:none;
    border: 1px dashed var(--rule);
    color: var(--copper);
    font-family: inherit;
    font-size: 13px;
    padding: 8px 12px;
    border-radius: 8px;
    width: 100%;
    margin-bottom: 20px;
  }
  .step-row{
    display:flex; gap:8px; align-items:flex-start;
    margin-bottom: 8px;
  }
  .step-row textarea{
    flex:1;
    min-height: 44px;
    font-family: inherit;
    background: var(--paper-raised);
    border: 1px solid var(--rule);
    border-radius: 8px;
    color: var(--ink);
    font-size: 16px;
    padding: 8px 10px;
    resize: vertical;
  }
  .danger-btn{
    background:none;
    border: 1px solid #7a3b34;
    color: #E5484D;
    font-family: inherit;
    font-size: 13px;
    padding: 8px 14px;
    border-radius: 8px;
    margin-top: 30px;
  }

  /* ---------- Collapsible "More details" section in the recipe form ---------- */
  .more-details{
    margin-top: 8px;
    border-top: 1px solid var(--rule);
    padding-top: 4px;
  }
  .more-details summary{
    list-style: none;
    cursor: pointer;
    padding: 14px 0;
    font-size: 13px;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--copper);
    font-weight: 600;
    display: flex;
    align-items: center;
    gap: 8px;
  }
  .more-details summary::-webkit-details-marker{ display:none; }
  .more-details summary::before{
    content: '+';
    font-family: monospace;
    font-size: 16px;
    transition: transform 0.15s;
  }
  .more-details[open] summary::before{ content: '−'; }
  .more-details textarea.form-field{ resize: vertical; font-family: inherit; }

  @media print{
    /* Named page so recipe/order prints stay full-page. Safari named-page support
       is incomplete; .label-block 5cm×3cm + page-break-after still sizes the paper. */
    @page sautero-label { size: 5cm 3cm; margin: 0; }
    body{ background:#fff; color:#000; }
    /* floating nav + feedback bubble + any open sheets never belong on paper (bod 4, 16.7.) */
    .no-print, .topbar, .chips, #listView, .icon-btn, .back-btn, .scale-note,
    .floating-nav, .global-feedback-btn, .sheet-overlay, .fab{ display:none !important; }
    #detailView{ display:block !important; }
    .detail-bar{ display:none !important; }
    .hero{ display:none; }
    .detail-content{ padding: 0; }
    .detail-cat{ color:#555; }
    h2.recipe-title{ color:#000; }
    .block h3{ color:#000; border-bottom:1px solid #ccc; padding-bottom:4px; }
    table.ing td{ color:#000; border-bottom:1px solid #ddd; }
    table.ing td.qty{ color:#000; }
    .method-list li::before{ background:#fff; border-color:#000; color:#000; }
    .allergen-row, .cost-block, .scale-bar, .scale-advanced, .notes-block{ display:none !important; }
    /* No interactive control belongs on paper (Richard, 26.7.: "v receptoch nechcem mať pri
       tlačení viditeľné add photo ani generovanie fotky ani pridávanie ingrediencií do databázy
       ani generovanie nutrícií"). Those were .add-row-btn buttons that no print rule covered —
       and listing them one by one would just leave the NEXT new button on the page. A button is
       a thing you tap; a printout is paper. None of the print sheets contain buttons. */
    button{ display:none !important; }

    /* Print Labels — takes over the whole printed page, overriding the recipe-print rules
       above (visibility:hidden/visible is more robust here than display, since it handles
       arbitrarily nested content without needing to enumerate every sibling). */
    /* Analýzy Chef's assistanta (bod 9): iba dokument, na bielom papieri, identita ostáva. */
    /* Cieľ tlače = JEDEN hárok (.ca-doc = #chefAnalysesDoc, jediný prvok); ostatné pravidlá sú pod jeho id,
       aby strážca print targets nečítal zdieľanú triedu ako cieľ (26. 7.: kuchynský hárok potiahol BEO). */
    body.printing-analysis .ca-doc, body.printing-analysis #chefAnalysesDoc{ display:block !important; position:static; inset:auto; left:0; overflow:visible; background:#fff; color:#111; }
    body.printing-analysis > *:not(#chefAnalysesDoc){ display:none !important; }
    body.printing-analysis #chefAnalysesDoc .ca-paper{ max-width:none; padding:0; }
    body.printing-analysis #chefAnalysesDoc .ca-kpi, body.printing-analysis #chefAnalysesDoc .ca-menu-btn, body.printing-analysis #chefAnalysesDoc .ca-sales input{ background:#fff; color:#111; border-color:#ccc; }
    body.printing-analysis #chefAnalysesDoc .ca-h1, body.printing-analysis #chefAnalysesDoc .ca-kpi-value{ color:#111; }
    body.printing-analysis #chefAnalysesDoc .ca-kpi-sentence, body.printing-analysis #chefAnalysesDoc .ca-note, body.printing-analysis #chefAnalysesDoc .ca-sub, body.printing-analysis #chefAnalysesDoc .ca-table th{ color:#444; }
    body.printing-analysis #chefAnalysesDoc .ca-table td{ border-color:#ddd; }
    body.printing-labels *{ visibility:hidden; }
    body.printing-labels .label-print-sheet, body.printing-labels .label-print-sheet *{ visibility:visible; }
    body.printing-labels .label-print-sheet{
      display:flex !important; flex-wrap:wrap; gap:0; align-content:flex-start;
      position:absolute; top:0; left:0; width:100%; background:#fff; padding:0;
    }
    /* Print Labels on A4 (mandate 2. 9. 2026, tile 7): the same 5×3 cm blocks, but on an office
       printer — a named A4 page, blocks flow left to right with a small gap and only break
       between rows; `page: auto` frees them from the label-roll page above. */
    @page sautero-a4 { size: A4; margin: 8mm; }
    body.printing-labels-a4 *{ visibility:hidden; }
    body.printing-labels-a4 .label-print-sheet, body.printing-labels-a4 .label-print-sheet *{ visibility:visible; }
    body.printing-labels-a4 .label-print-sheet{
      display:flex !important; flex-wrap:wrap; gap:3mm; align-content:flex-start;
      position:absolute; top:0; left:0; width:100%; background:#fff; padding:0;
      page: sautero-a4;
    }
    body.printing-labels-a4 .label-print-sheet .label-block{
      page: auto; page-break-after:auto; break-inside:avoid; margin:0;
    }

    /* Order List print — same visibility-swap trick as Print Labels. */
    /* Banquet Event Order — same visibility swap as the other three print paths (26.7.). */
    body.printing-beo *{ visibility:hidden; }
    /* The on-screen copy must stay hidden — it is the same document and would print twice. */
    body.printing-beo .beo-paper{ display:none !important; }
    body.printing-beo .beo-print-sheet, body.printing-beo .beo-print-sheet *{ visibility:visible; }
    body.printing-beo .beo-print-sheet{
      display:block !important; position:absolute; left:0; top:0; width:100%;
      background:#fff; color:#000; padding:0;
    }
    body.printing-orderlist *{ visibility:hidden; }
    body.printing-orderlist .order-print-sheet, body.printing-orderlist .order-print-sheet *{ visibility:visible; }
    body.printing-orderlist .order-print-sheet{
      display:block !important; position:absolute; top:0; left:0; width:100%; background:#fff; padding:16px;
    }

    /* Branded recipe print (bod 6, 16.7.) — same visibility-swap trick, its own letterhead
       instead of the plain default recipe print above. A sample template, not per-kitchen
       customizable yet (no logo/color storage exists) — see recipePrintBrandedSheet's own
       comment for the scope note. */
    body.printing-recipe-branded *{ visibility:hidden; }
    body.printing-recipe-branded .recipe-print-branded-sheet, body.printing-recipe-branded .recipe-print-branded-sheet *{ visibility:visible; }
    body.printing-recipe-branded .recipe-print-branded-sheet{
      display:block !important; position:absolute; top:0; left:0; width:100%; background:#fff; padding:24px; color:#1a1a1a;
    }
  }
  /* Branded print v2 (bod 4, 16.7. večer): Richard found v1 bland and the footer too faint.
     Print-safe by construction — everything reads at full contrast even when the browser
     strips background colors (the default): strong navy ink, doubled rules, structure over
     color. Two-column body (ingredients rail + method), letterpress-style letterhead. */
  .recipe-print-branded-sheet{ display:none; font-family:Georgia, 'Times New Roman', serif; color:#111110; }
  .rpb-accent-bar{ height:5px; background:#0BD8B6; border-radius:3px; margin-bottom:16px; }
  .rpb-letterhead{ display:flex; align-items:flex-end; justify-content:space-between; border-bottom:3px double #111110; padding-bottom:12px; margin-bottom:6px; }
  .rpb-kitchen{ font-size:22px; font-weight:700; color:#111110; letter-spacing:.01em; }
  .rpb-tag{ font-family:-apple-system,Arial,sans-serif; font-size:9.5px; letter-spacing:.22em; text-transform:uppercase; color:#1a7e6f; margin-top:3px; }
  .rpb-mark{ font-family:-apple-system,Arial,sans-serif; font-size:13px; font-weight:800; letter-spacing:.04em; color:#111110; background:#0BD8B6; border:2px solid #0BD8B6; border-radius:8px; padding:6px 10px; }
  .rpb-mark span{ font-weight:400; font-style:italic; font-family:Georgia,serif; color:#111110; }
  .rpb-title{ font-size:32px; line-height:1.15; margin:18px 0 2px 0; color:#111110; }
  .rpb-subtitle{ font-style:italic; font-size:14px; color:#3a4a5f; margin:2px 0 0 0; }
  .rpb-meta{ display:flex; gap:0; margin:16px 0 20px 0; border:1.5px solid #111110; border-radius:8px; overflow:hidden; }
  .rpb-meta-cell{ flex:1; padding:8px 12px; border-right:1.5px solid #111110; }
  .rpb-meta-cell:last-child{ border-right:none; }
  .rpb-meta-label{ font-family:-apple-system,Arial,sans-serif; font-size:8.5px; letter-spacing:.18em; text-transform:uppercase; color:#3a4a5f; }
  .rpb-meta-value{ font-family:-apple-system,Arial,sans-serif; font-size:13px; font-weight:700; color:#111110; margin-top:2px; }
  .rpb-columns{ display:flex; gap:26px; align-items:flex-start; }
  .rpb-col-ing{ flex:0 0 38%; }
  .rpb-col-steps{ flex:1; }
  .rpb-section-label{ font-family:-apple-system,Arial,sans-serif; font-size:11px; font-weight:800; letter-spacing:.16em; text-transform:uppercase; color:#111110; border-bottom:2px solid #0BD8B6; padding-bottom:5px; margin:0 0 10px 0; }
  .rpb-ing-table{ width:100%; border-collapse:collapse; font-family:-apple-system,Arial,sans-serif; font-size:12.5px; }
  .rpb-ing-table td{ padding:5px 0; border-bottom:1px solid #8a97a8; color:#111110; vertical-align:top; }
  .rpb-ing-table td.qty{ text-align:right; font-weight:700; white-space:nowrap; padding-left:10px; }
  .rpb-steps{ font-family:-apple-system,Arial,sans-serif; font-size:13px; line-height:1.65; padding-left:0; margin:0; list-style:none; counter-reset:rpbstep; }
  .rpb-steps li{ counter-increment:rpbstep; display:flex; gap:10px; margin-bottom:9px; }
  .rpb-steps li::before{ content:counter(rpbstep); flex:none; width:22px; height:22px; border:2px solid #1a7e6f; background:#0BD8B6; border-radius:50%; display:flex; align-items:center; justify-content:center; font-weight:800; font-size:11px; color:#111110; }
  .rpb-notes{ margin-top:20px; border-left:4px solid #0BD8B6; padding:2px 0 2px 14px; }
  .rpb-notes p{ font-style:italic; font-size:13px; color:#111110; margin:0; line-height:1.55; }
  /* Composition donut on the printed card (Richard, 17.7.) — inline SVG strokes, because
     browsers strip CSS backgrounds when printing but always render SVG fills/strokes. */
  .rpb-comp{ margin-top:18px; }
  .rpb-comp-flex{ display:flex; gap:20px; align-items:center; }
  .rpb-comp-legend{ flex:1; font-family:-apple-system,Arial,sans-serif; font-size:11.5px; color:#111110; }
  .rpb-comp-legend div{ display:flex; align-items:center; gap:7px; margin:3px 0; }
  .rpb-comp-legend i{ width:10px; height:10px; border-radius:3px; flex:none; display:inline-block; }
  .rpb-used-in{ margin-top:16px; }
  .rpb-used-in ul{ margin:0; padding-left:18px; font-family:-apple-system,Arial,sans-serif; font-size:12px; color:#111110; }
  .rpb-used-in li{ margin-bottom:3px; }
  .rpb-footer{ margin-top:28px; padding-top:10px; border-top:3px double #111110; font-family:-apple-system,Arial,sans-serif; font-size:10px; font-weight:600; color:#111110; display:flex; justify-content:space-between; }
  /* 5×3 cm = 50×30 mm. Brother QL-820NWB (support.brother.com spec, EU): max media 62 mm,
     max printing width 58 mm (720-dot head is 60.96 mm at 300 dpi; Brother publishes 58 mm).
     50 mm continuous (DK-2223 / DK-22223) fits. 30 mm is the HACCP die-cut height this sheet
     has used since day one. DK-11209 is 62×29 mm — 1 mm shorter; do not silently shrink
     the label to that roll. Named @page sautero-label (in @media print) applies only to
     .label-block so recipe/order prints stay full page — no document.head inject. */
  .label-print-sheet{ display:none; }
  .label-block{
    width:5cm; height:3cm; box-sizing:border-box;
    border:1px dashed #999; padding:0.12cm 0.18cm;
    page: sautero-label;
    page-break-inside:avoid; page-break-after:always; color:#000; font-family:-apple-system,Arial,sans-serif;
    display:flex; flex-direction:row; align-items:center; gap:0.12cm; overflow:hidden;
  }
  .label-block .label-text{ flex:1; min-width:0; display:flex; flex-direction:column; justify-content:center; }
  .label-block .label-name{ font-size:11px; font-weight:700; line-height:1.15; overflow-wrap:anywhere; }
  .label-block .label-useby{ font-size:9px; font-weight:700; margin-top:2px; }
  .label-block .label-meta{ font-size:7.5px; color:#333; margin-top:1px; line-height:1.25; }
  .label-block .label-qr{ width:1.15cm; height:1.15cm; flex:none; }
  .label-block .label-qr svg{ width:100%; height:100%; display:block; }
  /* BEO sheet — deliberately plain and dense, like the real ones: black on white, ruled
     blocks, no colour. A chef reads it on paper at 06:00, often photocopied. */
  /* Two different things that happen to look alike (fixed 26.7.):
       .beo-print-sheet  = the hidden element that gets PRINTED (#beoPrintSheet)
       .beo-paper        = the white sheet shown on screen in the detail view
     They shared one class, so `body.printing-beo .beo-print-sheet{visibility:visible}` matched
     BOTH and every "print just the kitchen" also printed the main sheet underneath. Styling is
     shared; the print target is not. */
  .beo-print-sheet, .beo-paper{ font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Arial,sans-serif; }
  .beo-print-sheet{ display:none; }
  /* On screen the BEO is shown as the PAPER it is about to become — white sheet, black text,
     the same markup that prints. What he checks on the phone is then literally what comes out
     of the printer, and the light block headers stay readable instead of sitting on the dark
     app background (26.7., seen on the phone before shipping). */
  .beo-paper{ background:#fff; color:#111; border-radius:12px; padding:16px 15px 20px 15px; }
  .beo-paper .beo-field b{ color:#555; }
  .beo-paper .beo-sub{ color:#444; }
  .beo-head{ display:flex; align-items:flex-start; justify-content:space-between; gap:12px;
    border-bottom:2px solid #111; padding-bottom:8px; margin-bottom:12px; }
  .beo-kitchen{ font-family:Georgia,serif; font-size:20px; font-weight:700; }
  .beo-brand{ font-size:10px; letter-spacing:.12em; text-transform:uppercase; color:#666; }
  .beo-doc{ text-align:right; font-size:11px; color:#333; }
  .beo-title{ font-size:17px; font-weight:700; margin:0 0 2px 0; }
  .beo-sub{ font-size:12px; color:#444; margin:0 0 12px 0; }
  .beo-grid{ display:grid; grid-template-columns:1fr 1fr; gap:0 18px; margin-bottom:12px; }
  /* One column on a phone. Two columns at 375px cut "120 expected" in half and clipped the
     e-mail address — seen on the device, not guessed. Paper is wide, a phone is not. */
  @media (max-width: 560px){ .beo-grid{ grid-template-columns:1fr; } }
  .beo-field{ border-bottom:1px solid #ddd; padding:4px 0; font-size:12px; display:flex; gap:8px;
    align-items:baseline; }
  .beo-field b{ min-width:88px; flex:none; color:#555; font-weight:600; }
  .beo-field span{ flex:1; min-width:0; overflow-wrap:anywhere; }
  .beo-block{ border:1px solid #bbb; margin-bottom:10px; }
  .beo-block h4{ margin:0; padding:5px 8px; background:#eee; font-size:11px; letter-spacing:.09em;
    text-transform:uppercase; border-bottom:1px solid #bbb; }
  .beo-block .beo-body{ padding:7px 9px; font-size:12.5px; line-height:1.55; white-space:pre-wrap; }
  .beo-sign{ display:flex; gap:28px; margin-top:22px; font-size:11px; color:#444; }
  .beo-sign div{ flex:1; border-top:1px solid #111; padding-top:4px; }
  .order-print-sheet{ display:none; }
  .olp-letterhead{ display:flex; align-items:baseline; justify-content:space-between; gap:12px;
    border-bottom:2px solid #111; padding-bottom:6px; margin-bottom:12px; }
  .olp-kitchen{ font-family:Georgia,serif; font-size:19px; font-weight:700; color:#000; }
  .olp-brand{ font-size:10px; letter-spacing:.12em; text-transform:uppercase; color:#666; }
  .order-print-sheet h2{ font-size:20px; margin:0 0 10px 0; }
  .order-print-sheet h3{ font-size:15px; margin:16px 0 6px 0; border-bottom:1px solid #ccc; padding-bottom:4px; }
  .order-print-sheet table{ width:100%; border-collapse:collapse; }
  .order-print-sheet td{ padding:5px 0; border-bottom:1px solid #eee; font-size:13px; }
  .order-print-sheet td.qty{ text-align:right; white-space:nowrap; padding-left:10px; }

/* ── Inline → trieda (desktop program, Richard 16. 8. 2026) ─────────────────────────
   Presun, nie úprava: každá trieda nesie PRESNE pôvodný inline reťazec. Dôkaz nuly
   vizuálnych zmien: scripts/style_move_proof.py (computed style pred/po, per prvok). */
.u-flex1{flex:1;}
.u-w100{width:100%;}

/* Dávka ①b — 33 čistých reťazcov, presun 1:1 (dôkaz: style_move_proof, default aj 375 px) */
.u-mb6px{margin-bottom:6px;}
.u-m0{margin:0;}
.u-flex1-minw0{flex:1; min-width:0;}
.u-m006px0{margin:0 0 6px 0;}
.u-fs18px{font-size:18px;}
.u-m0010px0{margin:0 0 10px 0;}
.u-oxvisible-fwwrap-p0{overflow-x:visible; flex-wrap:wrap; padding:0;}
.u-w100-taleft-mb8px{width:100%; text-align:left; margin-bottom:8px;}
.u-m008px0{margin:0 0 8px 0;}
.u-oyauto{overflow-y:auto;}
.u-p0{padding:0;}
.u-flex1-tacenter{flex:1; text-align:center;}
.u-posrelative{position:relative;}
.u-mr8px{margin-right:8px;}
.u-m004px0{margin:0 0 4px 0;}
.u-tacenter{text-align:center;}
.u-flex1-m0{flex:1; margin:0;}
.u-w100-mb8px{width:100%; margin-bottom:8px;}
.u-p4px18px0{padding: 4px 18px 0 18px;}
.u-mb10px{margin-bottom:10px;}
.u-flexnone{flex:none;}
.u-pbbalways{page-break-before:always;}
.u-flex1-minw90px{flex:1; min-width:90px;}
.u-mb2px{margin-bottom:2px;}
.u-flexnone-wsnowrap-m0{flex:none; white-space:nowrap; margin:0;}
.u-zind72{z-index:72;}
.u-fwt400-fs12px{font-weight:400; font-size:12px;}
.u-fs18px-flexnone{font-size:18px; flex:none;}
.u-fs14px{font-size:14px;}
.u-m0014px0{margin:0 0 14px 0;}
.u-m14px012p{margin:-14px 0 12px 0;}
.u-wsprewrap{white-space:pre-wrap;}
.u-fwwrap-gap8px{flex-wrap:wrap; gap:8px;}

/* Dávka ①c — 35 z 36 bezpečných dvojvýskytových (16 display + 16 s mazanou vlastnosťou
   vynechaných sitom). margin-bottom:4px VRÁTENÝ na inline: h1.title kompozit (0,1,1) by
   prebil utility triedu (0,1,0) — dôkaz to chytil ako 4px→16px; ide do ③ po jednom. */
.u2-bt1pxsolid-m14px0{border-top:1px solid var(--rule); margin:14px 0;}
.u2-curdefault{cursor:default;}
.u2-flex1-fs125px-p7px9px{flex:1; font-size:12.5px; padding:7px 9px;}
.u2-flex1-p16px0{flex:1; padding:16px 0;}
.u2-flexnone-w32px-h32px{flex:none; width:32px; height:32px;}
.u2-fs16px-lh14{font-size:16px; line-height:1.4;}
.u2-fs22px{font-size:22px;}
.u2-fonttabularn{font-variant-numeric:tabular-nums;}
.u2-fwt600{font-weight:600;}
.u2-gap8px{gap:8px;}
.u2-mb12px{margin-bottom:12px;}
.u2-mb8px{margin-bottom:8px;}
.u2-mr2px{margin-right:2px;}
.u2-mt22px{margin-top:22px;}
.u2-mt26px{margin-top:26px;}
.u2-mt28px{margin-top:28px;}
.u2-m6px08px0{margin:-6px 0 8px 0;}
.u2-m0016px0{margin:0 0 16px 0;}
.u2-m004px{margin:0 0 4px;}
.u2-m008px{margin:0 0 8px;}
.u2-m0-padd18px-fs13px-lh15{margin:0; padding-left:18px; font-size:13px; line-height:1.5;}
.u2-m14px04px-fs12px-ttuppercas-ls04em-op6{margin:14px 0 4px; font-size:12px; text-transform:uppercase; letter-spacing:.04em; opacity:.6;}
.u2-oxvisible-fwwrap{overflow-x:visible; flex-wrap:wrap;}
.u2-ohidden-textellipsis-wsnowrap{overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.u2-padd0-padd0{padding-left:0; padding-right:0;}
.u2-p018px8px{padding:0 18px 8px 18px;}
.u2-tacenter-mt10px{text-align:center; margin-top:10px;}
.u2-tdnone{text-decoration:none;}
.u2-w100-mt6px{width:100%; margin-top:6px;}
.u2-w100-taleft{width:100%; text-align:left;}
.u2-w120px-h120px-flexnone{width:120px; height:120px; flex:none;}
.u2-wauto-m0{width:auto; margin:0;}
.u2-wauto-p014px{width:auto; padding:0 14px;}
.u2-wordbreakall{word-break:break-all;}

/* Dávka ②a — margin-top:10px (JS margin-top nastavuje, nikdy nemaže — clear-analýza 16. 8.) */
.u-mt10px{margin-top:10px;}

/* Dávka ②b — margin-top:14px, width+mt8px, cursor:pointer (JS nastavuje-nemaže) */
.u-mt14px{margin-top:14px;}
.u-w100-mt8px{width:100%; margin-top:8px;}
.u-curpointer{cursor:pointer;}

/* Dávka ②c */
.u-w100-mt10px{width:100%; margin-top:10px;}
.u-mt8px{margin-top:8px;}
.u-w100-mt14px{width:100%; margin-top:14px;}

/* Dávka ②d — zvyšok margin-top rodiny; ② tým hotová */
.u-mt12px{margin-top:12px;}
.u-mt4px{margin-top:4px;}
.u-w100-mt12px{width:100%; margin-top:12px;}
.u-mt0{margin-top:0;}
.u-mt16px{margin-top:16px;}
.u-mt6px{margin-top:6px;}
.u-mt18px{margin-top:18px;}

/* Dávka ③a — color rodina; overené sitom style_clear_sieve: mazacie ciele (#msModeFull,
   #msModeIngredients a ich potomkovia, .add-cat-btn) tieto reťazce NENESÚ */
.u3-cinkdim{color:var(--ink-dim);}
.u3-cink{color:var(--ink);}
.u3-cff7a68{color:#E5484D;}
.u3-csage{color:var(--sage);}
.u3-ccopper{color:var(--copper);}

/* Dávka ③b — background/border-radius/min-height + kombinované; sito potvrdilo, že žiadny
   z nich nesedí na prvku, ktorému JS vlastnosť maže (jediné rizikové ostáva max-height/.sheet) */
.u3-minh60px{min-height:60px;}
.u3-fs105px-cvarink-tacenter{font-size:10.5px; color:var(--ink-faint); text-align:center;}
.u3-cvarink-fs12px{color:var(--ink-faint); font-size:12px;}
.u3-minh18px-mb6px{min-height:18px; margin-bottom:6px;}
.u3-c333{color:#333;}
.u3-bgff7a68{background:#E5484D;}
.u3-flex1-cvarink-minw0-ohidden-toellips-wsnow{flex:1; color:var(--ink-dim); min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.u3-ffgeorgi-fstitalic-fs19px-lett001em-cvarco{font-family:Georgia,'Times New Roman',serif; font-style:italic; font-size:19px; letter-spacing:0.01em; color:var(--copper);}
.u3-fwt700-fs12px-m12px04-cvarcop{font-weight:700; font-size:12px; margin:12px 0 4px; color:var(--copper);}
.u3-bgnone-bnone-cvarcop-fs12px-curspointe-p0{background:none;border:none;color:var(--copper);font-size:12px;cursor:pointer;padding:0;}
.u3-minh70px{min-height:70px;}
.u3-taleft-bgvarpap-b1pxsol-br14px-p18px16{text-align:left; background:var(--paper-raised); border:1px solid var(--rule); border-radius:14px; padding:18px 16px;}
.u3-fs15px-fwt700-cvarink-mb6px{font-size:15px; font-weight:700; color:var(--ink); margin-bottom:6px;}
.u3-m0012px-cvarink-fs135px-lh16{margin:0 0 12px 0; color:var(--ink-dim); font-size:13.5px; line-height:1.6;}
.u3-c8aa{color:#8aa;}

/* Dávka ③c — opacity/accent rodina. margin-bottom:4px VYNECHANÝ automaticky:
   scripts/inline_style_exclusions.json (špecificita h1.title, vrátené v ①c) */
.u4-op65-mt8px{opacity:.65; margin-top:8px;}
.u4-op65-mb8px{opacity:.65; margin-bottom:8px;}
.u4-op65-mt6px{opacity:.65; margin-top:6px;}
.u4-op7{opacity:.7;}
.u4-w100-taleft-mt10px{width:100%; text-align:left; margin-top:10px;}
.u4-w20px-h20px-accevarcop{width:20px; height:20px; accent-color:var(--copper);}
.u4-op65{opacity:.65;}
/* AI Spend dlaždica (22. 8. 2026) — vzhľad pruhu/trendu patrí sem, nie do inline štýlov modulu.
   Dynamické hodnoty (šírka + farba pruhu) nastavuje ai_spend.js na elemente cez JS po vykreslení. */
.ais-gauge-row{align-items:center; gap:12px;}
.ais-gauge-track{height:12px; border-radius:999px; background:rgba(127,127,127,.18); overflow:hidden;}
.ais-gauge-fill{height:100%; width:0;}
.ais-warn{color:#E5484D; margin-top:4px;}
.ais-trend{width:100%; height:44px; overflow:visible;}
.ais-sheet{max-height:85vh; overflow-y:auto;}
.ais-credit-banner{grid-column:1/-1; padding:10px 4px 4px; text-align:left;}
.ais-credit-banner .sheet-text{margin:4px 0 0;}

/* Riadkové flex-layouty (Merač, 22. 8. 2026, dávka ①). Presúva sa CELÝ atribút, nie
   vlastnosť: `inline_style_guard` počíta atribúty, takže lúpanie po vlastnostiach
   meradlom nepohne. Prvky preverené `style_clear_sieve.py` (nerizikové) a držané
   `style_move_proof` na 1280 aj 375 px. */
.u-row-between-wrap{display:flex; align-items:center; justify-content:space-between; gap:16px; flex-wrap:wrap; row-gap:6px;}
.u-row-gap4{display:flex; align-items:center; gap:4px;}
.u-row-gap8{display:flex; gap:8px; align-items:center;}

/* Opakované celé atribúty, dávka ② (Merač, 22. 8. 2026). Do dávky idú LEN reťazce,
   ktorých počet v súbore sa ROVNÁ počtu prvkov v statickom DOM — inak by textová náhrada
   zasiahla aj kópiu vnútri JS šablóny (`width:100%; height:${pct}%` je dynamická väzba
   a trieda by ju zabila). Vyradený aj `border:none; … border-top:…` na <button>: tam
   trieda prehráva so špecifickejším pravidlom a tlačidlo dostane UA rámik. */
.u-mh320-ovya{max-height:320px; overflow-y:auto;}
.u-row-gap8-ptr{display:flex; align-items:center; gap:8px; cursor:pointer;}
.u-flex-gap8{display:flex; gap:8px;}
.u-note-box{text-align:left; max-height:38vh; overflow-y:auto; background:var(--paper-raised); border:1px solid var(--rule); border-radius:12px; padding:14px 16px; margin:14px 0; font-size:14px; line-height:1.55; color:var(--ink-dim);}

/* Dávka ③ (Merač, 22. 8.) — jednodeklaračné atribúty BEZ kópie v JS šablóne
   (počet v súbore == počet mimo <script>). Vyradené tri, ktoré padli na dôkaze:
   dva, kde sa trieda vôbec nepridala (atribúty nesusedili), a jeden na <h1>,
   kde trieda prehráva so špecifickejším pravidlom. */
.u-b3-m14px06px0{margin:14px 0 6px 0;}
.u-b3-p14px16px1{padding:14px 16px 100px 16px;}
.u-b3-fw700{font-weight:700;}
.u-b3-fs13px{font-size:13px;}
.u-b3-p010px12px{padding:0 10px 12px 10px;}
.u-b3-mh88vh{max-height:88vh;}
.u-b3-mh44px{min-height:44px;}
.u-b3-o08{opacity:0.8;}
.u-b3-cvarinkfai{color:var(--ink-faint);}
.u-b3-mt3px{margin-top:3px;}
.u-b3-mb16px{margin-bottom:16px;}
.u-b3-zi200{z-index:200;}
.u-b3-mw420px{max-width:420px;}
.u-b3-mh80vh{max-height:80vh;}
.u-b3-mh85vh{max-height:85vh;}
.u-b3-m018px12px{margin:0 18px 12px 18px;}
.u-b3-m6px000{margin:6px 0 0 0;}
.u-b3-mh82vh{max-height:82vh;}
.u-b3-p4px18px10{padding:4px 18px 100px 18px;}
.u-b3-m018px10px{margin: 0 18px 10px 18px;}
.u-b3-p4px18px40{padding: 4px 18px 40px 18px;}
.u-b3-p16px18px4{padding: 16px 18px 40px 18px;}
.u-b3-m0012px0{margin:0 0 12px 0;}
.u-b3-mh92vh{max-height:92vh;}
.u-b3-zi70{z-index:70;}
.u-b3-oxauto{overflow-x:auto;}
.u-b3-zi120{z-index:120;}
.u-b3-m6px010px0{margin:6px 0 10px 0;}

/* ROZMERY A ROZLOŽENIE — dávka ④ (Merač, 22. 8. 2026, zadal John).
   Desktop blokujú ROZMERY, nie farby: `style="width:320px"` prebije akékoľvek pravidlo
   pre veľkú obrazovku, takže druhý vzhľad sa nedá spraviť pravidlom, len prepisovaním.
   V dávke sú LEN atribúty s výhradne rozmerovými/rozložovacími vlastnosťami, bez kópie
   v JS šablóne a mimo sita `style_clear_sieve`. `display:none` je správanie a nie je tu.
   Vyradený `margin-bottom:18px` na <h1>: trieda tam prehráva so špecifickejším pravidlom
   (18px -> 16px) — a to sa zo súboru prečítať nedá, ukáže to až `--compare`. */
.u-r-mt18pxw100{margin-top:18px; width:100%;}
.u-r-dflexaicenter{display:flex; align-items:center; gap:8px;}
.u-r-fnonemw96px{flex:none; max-width:96px;}
.u-r-dflexaicenter2{display:flex; align-items:center; gap:4px; flex-wrap:wrap; justify-content:flex-end; row-gap:2px;}
.u-r-dinlineaicenter{display:inline-flex; align-items:center; gap:8px;}
.u-r-wautop016px{width:auto; padding:0 16px;}
.u-r-dflexg8px{display:flex; gap:8px; justify-content:center; margin:14px 0;}
.u-r-mh34pxmb6px{min-height:34px; margin-bottom:6px;}
.u-r-aicenterg8px{align-items:center; gap:8px; margin-bottom:6px;}
.u-r-m2px010mh18px{margin:-2px 0 10px 0; min-height:18px;}
.u-r-dflexaicenter3{display:flex; align-items:center; gap:12px; margin:4px 0 12px 0;}
.u-r-w100dblock{width:100%; display:block;}
.u-r-mlauto{margin-left:auto;}
.u-r-dflexg8px2{display:flex; gap:8px; margin:6px 0 10px 0;}
.u-r-dflexfwwrap{display:flex; flex-wrap:wrap; align-items:center; gap:6px 10px; margin-top:8px;}
.u-r-mt0f1{margin-top:0; flex:1;}
.u-r-mb8pxfwwrap{margin-bottom:8px; flex-wrap:wrap; gap:6px;}
.u-r-dnoneimm10px0{display:none !important; margin:10px 0;}
.u-r-mt2px{margin-top:2px;}
.u-r-dflexjccenter{display:flex; justify-content:center; margin:8px 0;}
.u-r-dflexfwwrap2{display:flex; flex-wrap:wrap; gap:8px; margin-bottom:10px;}
.u-r-mh18pxm008px{min-height:18px; margin:0 0 8px;}
.u-r-w100mt16px{width:100%; margin-top:16px;}

/* ROZMERY ZMIEŠANÉ — dávka ⑤ (Merač, 22. 8. 2026). Atribúty, kde je rozmer spolu
   s farbou/rámikom: desktop blokuje ten rozmer rovnako, takže ide von celý atribút.
   Predikát ako v ④: mimo <script>, bez kópie v šablóne, mimo sita, bez display:none.
   Vyradený (druhýkrát) `margin-bottom:18px` na <h1> — špecificita, 18px -> 16px. */
.u-m1-dflexaicente{display:flex; align-items:center; gap:8px; width:100%; padding:10px 14px; background:none; border:none; text-align:left; font-size:13px; color:var(--ink); cursor:pointer; border-top:1px solid var(--rule);}
.u-m2-tacentem10px0{text-align:center; margin:10px 0 0 0; color:var(--ink-faint); font-size:12px;}
.u-m3-b1pxsobrgba2{border:1px solid var(--sage); background:rgba(255,197,61,0.08); border-radius:12px; padding:12px 14px; margin:0 0 16px 0; font-size:13px; line-height:1.6;}
.u-m4-w100bnone{width:100%; background:none; border:1px solid var(--rule);}
.u-m5-tacentemt16px{text-align:center; margin-top:16px;}
.u-m6-prelatdflex{position:relative; display:flex; align-items:center; gap:10px; margin-top:10px;}
.u-m7-mt18pxbvarpa{margin-top:18px; background:var(--paper-raised); border:1px solid var(--rule); border-radius:14px; overflow:hidden;}
.u-m8-w100bnone{width:100%; border:none; border-radius:0; display:flex; align-items:center; justify-content:space-between; padding:12px 14px;}
.u-m9-tacentemh18px{text-align:center; min-height:18px;}
.u-m10-mh60vhoyauto{max-height:60vh; overflow-y:auto;}
.u-m11-mh62vhoyauto{max-height:62vh; overflow-y:auto;}
.u-m12-mh38vhoyauto{max-height:38vh; overflow-y:auto; white-space:pre-wrap; font-size:15px; line-height:1.65;}
.u-m13-br12pxfnone{border-radius:12px; flex:none;}
.u-m14-dflexaicente{display:flex; align-items:center; gap:8px; width:100%; padding:10px 14px; background:none; border:none; text-align:left; font-size:13px; color:var(--ink); cursor:pointer;}
.u-m15-b1a1a1cfff{background:#1a1a1a; color:#fff; border:none; padding:5px 14px; border-radius:6px; font-size:12px; font-weight:600; cursor:pointer;}
.u-m16-taleftm0014p{text-align:left; margin:0 0 14px 0;}
.u-m17-mt8pxfs13px{margin-top:8px; font-size:13px; line-height:1.6; color:var(--ink-dim);}
.u-m18-dflexaiflexs{display:flex; align-items:flex-start; gap:10px; text-align:left; margin:0 0 14px 0; cursor:pointer;}
.u-m19-w100mt14px{width:100%; margin-top:14px; text-align:left;}
.u-m20-w100mt10px{width:100%; margin-top:10px; text-align:left;}
.u-m21-fw700mb4px{font-weight:700; margin-bottom:4px;}
.u-m22-fs13pxo85{font-size:13px; opacity:.85; margin-bottom:10px;}
.u-m23-mt22pxpt16px{margin-top:22px; padding-top:16px; border-top:1px solid var(--line, rgba(255,255,255,0.1));}
.u-m24-w100mt14px{width:100%; margin-top:14px; color:#E5484D; border-color:#E5484D;}
.u-m25-bfffp16px{background:#fff; padding:16px; border-radius:12px; display:inline-block; margin-top:8px;}
.u-m26-prelatmw420px{position:relative; max-width:420px; margin:16px auto 0 auto; border-radius:16px; overflow:hidden; background:#000;}
.u-m27-w100mt10px{width:100%; margin-top:10px; opacity:.5;}
.u-m28-fs44pxlh1{font-size:44px; line-height:1; margin:6px 0 10px 0;}
.u-m29-bfffp16px{background:#fff; padding:16px; border-radius:12px; display:inline-block; margin:8px 0;}
.u-m30-fs28pxfw700{font-size:28px; font-weight:700; letter-spacing:.08em; margin:6px 0 14px;}
.u-m31-mt18pxtaleft{margin-top:18px; text-align:left; display:block;}
.u-m32-fs42pxlh1{font-size:42px; line-height:1; margin:6px 0 10px 0;}
.u-m33-dflexaicente{display:flex; align-items:center; gap:8px; font-size:14px; color:var(--ink-dim); margin:10px 0;}
.u-m34-fw800fs14px{font-weight:800; font-size:14px; flex:1;}
.u-m35-prelatwauto{position:relative; width:auto; display:flex; align-items:center; gap:6px; padding:0 4px;}
.u-m36-wautop08px{width:auto; padding:0 8px; gap:5px; font-size:12px; font-weight:600; color:var(--copper);}
.u-m37-m4px00fs125px{margin:4px 0 0 0; font-size:12.5px; color:var(--ink-dim);}
.u-m38-pstickt0{position:sticky; top:0; z-index:5; background:var(--paper-raised); margin:0 -20px 10px -20px; padding:0 20px 10px 20px; border-bottom:1px solid var(--rule);}
.u-m39-m0cvarco{margin:0; color:var(--copper);}
.u-m40-mh340pxfs16px{min-height:340px; font-size:16px; line-height:1.6;}
.u-m42-oyautof1{overflow-y:auto; flex:1;}
.u-m43-prelatdinlin{position:relative; display:inline-block; overflow:hidden; border-radius:10px; touch-action:none;}
.u-m44-mw100mh52vh{max-width:100%; max-height:52vh; display:block; user-select:none; -webkit-user-drag:none; pointer-events:none;}
.u-m45-pabsoll13px{position:absolute; left:-13px; top:-13px; width:26px; height:26px; border-radius:50%; background:var(--teal9); border:3px solid #111110; box-shadow:0 1px 6px rgba(0,0,0,0.5); touch-action:none;}
.u-m46-pabsolr13px{position:absolute; right:-13px; top:-13px; width:26px; height:26px; border-radius:50%; background:var(--teal9); border:3px solid #111110; box-shadow:0 1px 6px rgba(0,0,0,0.5); touch-action:none;}
.u-m47-pabsoll13px{position:absolute; left:-13px; bottom:-13px; width:26px; height:26px; border-radius:50%; background:var(--teal9); border:3px solid #111110; box-shadow:0 1px 6px rgba(0,0,0,0.5); touch-action:none;}
.u-m48-pabsolr13px{position:absolute; right:-13px; bottom:-13px; width:26px; height:26px; border-radius:50%; background:var(--teal9); border:3px solid #111110; box-shadow:0 1px 6px rgba(0,0,0,0.5); touch-action:none;}
.u-m49-mh40vhoyauto{max-height:40vh; overflow-y:auto; margin:10px 0;}
.u-m50-mh45vhoyauto{max-height:45vh; overflow-y:auto; margin:10px 0;}
.u-m51-mh32vhoyauto{max-height:32vh; overflow-y:auto; margin:10px 0;}
.u-m52-fs15pxmt6px{font-size:15px; margin-top:6px;}
.u-m53-oyautomh0{overflow-y:auto; min-height:0;}
.u-m54-mt12pxmh300px{margin-top:12px; max-height:300px; overflow-y:auto;}
.u-m55-oyautomb10px{overflow-y:auto; margin-bottom:10px;}
.u-m56-mh240pxoyauto{max-height:240px; overflow-y:auto;}
.u-m57-mh44vhoyauto{max-height:44vh; overflow-y:auto; margin:10px 0;}
.u-m58-mh42vhoyauto{max-height:42vh; overflow-y:auto; margin:10px 0;}

/* ROZDELENÉ ATRIBÚTY — dávka ⑥ (Merač, 22. 8. 2026). Niesli `display:none` V ZMESI
   so vzhľadom. `display:none` je SPRÁVANIE (appka ním panel skrýva za behu) a v atribúte
   ZOSTÁVA; vzhľad ide sem. Atribút prežije, takže `total` sa nepohne — ale
   `staticky_vzhlad` klesne, lebo zvyšok je už čisté správanie. Presne na toto bola
   ráčňa rozdelená na tri populácie. Dôkaz: režim priznaného zvyšku (Overovač, 335). */
.u-c01{width:100%; margin-top:8px;}
.u-c02{width:auto; padding:0 8px; gap:5px; font-size:12px; font-weight:600; color:var(--copper);}
.u-c03{color:var(--copper); margin-bottom:12px;}
.u-c04{margin-bottom:10px;}
.u-c05{padding:0 18px 8px 18px;}
.u-c06{margin-bottom:14px;}
.u-c07{position:absolute; top:1px; right:1px; width:9px; height:9px; border-radius:50%; background:#0BD8B6; box-shadow:0 0 0 2px #111110;}
.u-c08{position:absolute; top:6px; right:6px; width:8px; height:8px; border-radius:50%; background:var(--teal9);}
.u-c09{position:absolute; left:16px; right:16px; z-index:65; margin-top:6px; background:var(--bg-raised, #10233C); border:1px solid var(--rule); border-radius:14px; box-shadow:0 12px 32px rgba(0,0,0,0.55); max-height:60vh; overflow-y:auto; padding:6px;}
.u-c10{position:fixed; bottom:0; left:0; right:0; z-index:9999; background:var(--teal9); color:#1a1a1a; padding:10px 16px; text-align:center; font-size:13px; font-weight:600; align-items:center; justify-content:center; gap:10px;}
.u-c11{background:rgba(11,216,182,.12); border:1px solid #0BD8B6; border-radius:12px; padding:12px 14px; margin-bottom:14px;}
.u-c12{margin-top:8px;}
.u-c13{margin-top:12px;}
.u-c14{width:100%; margin-bottom:8px;}
.u-c15{margin-bottom:8px;}
.u-c16{text-align:center;}
.u-c17{position:absolute; top:4px; right:4px; width:8px; height:8px; border-radius:50%; background:var(--teal9); border:1.5px solid var(--bg);}
.u-c18{position:fixed; left:16px; right:16px; bottom:calc(84px + env(safe-area-inset-bottom, 0px)); z-index:55; background:var(--teal9); color:#111110; border-radius:14px; padding:12px 16px; box-shadow:0 8px 24px rgba(0,0,0,0.5); align-items:center; gap:12px;}
.u-c19{position:absolute; top:2px; right:2px; min-width:15px; height:15px; padding:0 3px; border-radius:8px; background:var(--teal9); color:#111110; font-size:10px; font-weight:800; line-height:15px; text-align:center;}
.u-c20{width:8px; height:8px; border-radius:50%; background:var(--teal9); flex:none;}
.u-c21{width:100%; margin-top:12px;}
.u-c22{margin-bottom:10px;}
.u-c23{margin-top:10px;}
.u-c24{position:fixed; left:0; right:auto; max-width:78vw; bottom:calc(12px + env(safe-area-inset-bottom, 0px)); z-index:60; background:var(--teal9); color:#111110; font-size:12.5px; font-weight:700; text-align:right; white-space:nowrap; overflow:hidden; padding:9px 24px 9px 16px; cursor:pointer; border-radius:0 16px 16px 0; box-shadow:0 6px 20px rgba(0,0,0,0.45); transform:translateX(calc(60px - 100%)); transition:transform 0.25s;}
/* len pre selftest template_style_proof (Overovacov pripad A: znacka rozhoduje) */
.u-disp-block-t{margin-top:8px; display:block;}

/* ── Desktop ERP shell (Richard 27. 8. 2026) — hand-written, no Tailwind. Admin-only wide layout. */
:root { --desktop-erp-sidebar-w: 220px; }
#desktopErpShell.desktop-erp-shell {
  display: none;
  position: fixed;
  left: 0;
  top: 0;
  bottom: 0;
  width: var(--desktop-erp-sidebar-w);
  z-index: 120;
  flex-direction: column;
  background: var(--sand1);
  border-right: 1px solid var(--sand-rule);
  color: #fff;
}
body.desktop-erp-active #desktopErpShell { display: flex; }
#desktopErpMain.desktop-erp-main {
  display: none;
  position: fixed;
  left: var(--desktop-erp-sidebar-w);
  top: 0;
  right: 0;
  bottom: 0;
  overflow-y: auto;
  z-index: 10;
  box-sizing: border-box;
}
body.desktop-erp-active #desktopErpMain.desktop-erp-main { display: block; }
body.desktop-erp-active #desktopErpMain.desktop-erp-main[aria-hidden="true"] { display: none; }
body.desktop-erp-active [id$="View"] {
  margin-left: var(--desktop-erp-sidebar-w);
  max-width: calc(100% - var(--desktop-erp-sidebar-w));
  box-sizing: border-box;
}
body.desktop-erp-active #floatingNav { margin-left: var(--desktop-erp-sidebar-w); }
.desktop-erp-brand {
  padding: 16px 14px 10px;
  font-family: var(--font-brand);
  font-size: 17px;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--teal11);
}
.desktop-erp-nav {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 6px 8px 12px;
  overflow-y: auto;
  flex: 1;
}
.desktop-erp-nav-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 10px 12px;
  border: none;
  border-radius: 8px;
  background: transparent;
  color: #8D8D86;
  font-size: 13px;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
}
.desktop-erp-nav-item:hover { background: rgba(11, 216, 182, 0.08); color: #fff; }
.desktop-erp-nav-icon { font-size: 16px; width: 22px; text-align: center; flex: none; }
/* ZADANIE §3A: the row height is a fixed 38px, so the label must never take a second line —
   a long module name is cut with an ellipsis and kept readable by the title attribute. */
.desktop-erp-nav-label { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.desktop-erp-nav-item[aria-current="page"] {
  background: rgba(11, 216, 182, 0.12);
  color: var(--teal11);
}
.desktop-erp-nav-section {
  margin: 10px 0 4px;
  padding: 0 12px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #64748b;
}
.desktop-erp-nav-section:first-child { margin-top: 0; }
#desktopErpHomePanel {
  display: none;
  padding: 24px 28px 40px;
  min-height: 100%;
  box-sizing: border-box;
}
.desktop-erp-home-title { margin: 0 0 6px; font-size: 22px; font-weight: 700; }
.desktop-erp-home-sub { margin: 0 0 20px; color: #8D8D86; font-size: 14px; }
.desktop-erp-kpi-row {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 12px;
  margin-bottom: 20px;
}
@media (max-width: 1400px) { .desktop-erp-kpi-row { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 1200px) { .desktop-erp-kpi-row { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.desktop-erp-kpi {
  display: block;
  width: 100%;
  padding: 14px 16px;
  border-radius: 8px;
  border: 1px solid var(--sand-rule);
  background: var(--sand2);
  margin: 0;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
}
.desktop-erp-kpi:hover { border-color: var(--teal11); }
.desktop-erp-kpi:focus-visible,
.desktop-erp-mod-card:focus-visible {
  outline: 2px solid var(--teal11);
  outline-offset: 2px;
}
.desktop-erp-kpi-label {
  display: block;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #64748b;
}
.desktop-erp-kpi-value {
  display: block;
  margin: 6px 0 0;
  font-family: var(--font-data);
  font-size: 22px;
  font-weight: 700;
  color: var(--light);
}
.desktop-erp-home-hint { color: #8D8D86; font-size: 13px; line-height: 1.5; max-width: 52rem; }
.desktop-erp-mod-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
  margin-top: 16px;
}
@media (max-width: 1200px) { .desktop-erp-mod-grid { grid-template-columns: 1fr; } }
/* Empty kitchen: four steps instead of a dashboard (INVESTOR_PROTO FÁZA 5). */
.desktop-erp-first-steps { margin: 0 0 18px; }
.desktop-erp-first-steps-title { margin: 0 0 6px; font-size: 20px; font-weight: 700; }
.desktop-erp-first-steps-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; margin-top: 14px; }
.desktop-erp-first-step {
  display: flex; align-items: center; gap: 14px; min-height: 64px; padding: 14px 16px;
  border-radius: 12px; border: 1px solid var(--sand-rule); background: var(--sand2);
  font: inherit; color: inherit; text-align: left; cursor: pointer; -webkit-appearance: none; appearance: none;
}
.desktop-erp-first-step:hover { border-color: var(--teal11); }
.desktop-erp-first-step-n {
  flex: none; width: 32px; height: 32px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center;
  background: rgba(11,216,182,0.16); color: var(--teal11); font-weight: 700;
}
.now-first-task { font-weight: 700; }
.desktop-erp-mod-card {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  min-height: 220px;
  padding: 18px 18px 28px;
  border-radius: 12px;
  border: 1px solid var(--sand-rule);
  background: var(--sand2);
  margin: 0;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
}
.desktop-erp-mod-card:hover { border-color: var(--teal11); }
.desktop-erp-mod-title {
  display: block;
  font-size: 16px;
  font-weight: 700;
  color: var(--light);
}
.desktop-erp-mod-caption {
  display: block;
  margin-top: 4px;
  font-size: 12px;
  color: #8D8D86;
}
.desktop-erp-mod-chart {
  display: block;
  margin-top: 16px;
  min-height: 88px;
  flex: 1;
}
.desktop-erp-mod-svg { width: 100%; height: 88px; display: block; }
.desktop-erp-mod-empty {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 88px;
  color: #8D8D86;
  font-size: 22px;
  font-weight: 700;
}
.desktop-erp-mod-go {
  position: absolute;
  right: 14px;
  bottom: 14px;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--teal11);
  box-shadow: 0 0 0 3px var(--sand1);
}
.desktop-erp-home-actions { margin: 0 0 16px; display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.desktop-erp-new-recipe {
  border: 1px solid var(--teal11);
  border-radius: 8px;
  background: rgba(11, 216, 182, 0.12);
  color: var(--teal11);
  font-size: 13px;
  font-weight: 700;
  padding: 8px 14px;
  cursor: pointer;
  min-height: 44px;
}
.desktop-erp-demo-toggle {
  border: 1px solid var(--teal11);
  border-radius: 8px;
  background: rgba(11, 216, 182, 0.08);
  color: var(--teal11);
  font-size: 13px;
  font-weight: 700;
  padding: 8px 14px;
  cursor: pointer;
  min-height: 44px;
}
.desktop-erp-demo-toggle.is-on {
  background: rgba(11, 216, 182, 0.28);
}
.desktop-erp-schedule-empty {
  display: block;
  color: #8D8D86;
  font-size: 13px;
  font-weight: 600;
  padding: 8px 0 4px;
}
.desktop-erp-schedule {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 10px;
  width: 100%;
  margin: 8px 0 0;
  padding: 16px 16px 12px;
  border: 1px solid var(--sand-rule);
  border-radius: 10px;
  background: var(--sand2);
  color: var(--light);
  text-align: left;
  cursor: pointer;
  font: inherit;
}
.desktop-erp-schedule:hover { border-color: var(--teal11); }
.desktop-erp-schedule-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px 16px;
}
.desktop-erp-schedule-title {
  font-size: 15px;
  font-weight: 700;
  color: var(--teal11);
}
.desktop-erp-schedule-peak { font-size: 12px; color: #8D8D86; }
.desktop-erp-schedule-banner {
  font-size: 12px;
  font-weight: 600;
  color: var(--on-amber);
  background: var(--amber);
  border-radius: 6px;
  padding: 6px 10px;
}
.desktop-erp-schedule-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 14px;
}
.desktop-erp-schedule-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  color: #8D8D86;
}
.desktop-erp-schedule-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex: none;
}
.desktop-erp-schedule-svg { display: block; width: 100%; height: auto; }

/* ERP module canvas — office density. Phone .home-grid / .home-tile stay untouched.
   Every rule here is prefixed body.desktop-erp-active (U6 + Mobile toggle). */
body.desktop-erp-active .home-grid{
  max-width: none;
  margin: 0;
  grid-template-columns: repeat(auto-fill, minmax(148px, 1fr));
  gap: 8px;
  padding: 8px 20px 32px;
}
body.desktop-erp-active #checkListTileGrid,
body.desktop-erp-active #checkListTopTileGrid{
  grid-template-columns: repeat(auto-fill, minmax(148px, 1fr)) !important;
  max-width: none;
  margin: 0;
}
body.desktop-erp-active .home-tile{
  aspect-ratio: auto;
  min-height: 44px;
  flex-direction: row;
  justify-content: flex-start;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  border-radius: 8px;
  text-align: left;
}
body.desktop-erp-active .home-tile-icon{
  width: 36px;
  height: 36px;
  font-size: 22px;
  border-radius: 8px;
}
body.desktop-erp-active .home-tile-label{
  text-align: left;
  overflow-wrap: anywhere;
}
/* Phone tiles stay a square icon+label. Desktop ERP adds the Odoo-style count
   on the right — same number the opened shelf lists. */
.home-tile-count{ display: none; }
body.desktop-erp-active .home-tile-count{
  display: inline-block;
  margin-left: auto;
  flex: none;
  font-size: 18px;
  font-weight: 700;
  line-height: 1;
  color: var(--teal11);
  font-variant-numeric: tabular-nums;
}
body.desktop-erp-active .home-tile.cl-tile-wide{
  grid-column: 1 / -1;
  min-height: 64px;
  padding: 12px 16px 14px;
}
body.desktop-erp-active .cl-tile-wide .home-tile-icon{
  font-size: 36px;
  width: auto;
  height: auto;
}
body.desktop-erp-active .title.display{
  font-size: 22px;
  margin: 4px 0 8px;
}
/* Richard, 1. 9. 2026: the ERP Home screen is one wide Events card over a 2×2 of large module
   cards, not a five-across strip of thumbnails. Five 20 %-wide cards on a 1440px screen left
   each chart 230px with a 64px sparkline nobody could read. */
body.desktop-erp-active .desktop-erp-mod-grid{
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
}
body.desktop-erp-active .desktop-erp-mod-grid.is-events{ grid-template-columns: 1fr; }
@media (max-width: 1200px){
  body.desktop-erp-active .desktop-erp-mod-grid{ grid-template-columns: 1fr; }
}
body.desktop-erp-active .desktop-erp-mod-card{ min-height: 250px; padding: 16px 16px 28px; }
/* HACCP card: fridges 1–12 as a chip strip, the selected one drawn as a temperature line (3. 9. 2026). */
.desktop-erp-fridge-strip{ display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 4px; margin: 8px 0 6px; }
.desktop-erp-fridge-chip{
  display: flex; align-items: center; justify-content: space-between; gap: 4px;
  padding: 3px 7px; border-radius: 6px; border: 1px solid var(--sand-rule);
  background: var(--sand2); font-family: var(--font-data); font-size: 11px; color: var(--ink-dim);
  cursor: pointer; min-width: 0; line-height: 1.25;
}
.desktop-erp-fridge-chip:hover{ border-color: var(--teal11, #0BD8B6); }
.desktop-erp-fridge-chip.is-on{ border-color: var(--teal11, #0BD8B6); box-shadow: inset 0 0 0 1px var(--teal11, #0BD8B6); color: var(--light); }
.desktop-erp-fridge-chip.is-out{ border-color: var(--copper, #C98A4B); }
.desktop-erp-fridge-chip.is-out .desktop-erp-fridge-t{ color: var(--copper, #C98A4B); font-weight: 700; }
.desktop-erp-fridge-n{ font-weight: 700; color: var(--light); }
.desktop-erp-fridge-t{ white-space: nowrap; }
body.desktop-erp-active .desktop-erp-mod-svg,
body.desktop-erp-active .desktop-erp-mod-chart,
body.desktop-erp-active .desktop-erp-mod-empty{ min-height: 96px; height: 96px; }
body.desktop-erp-active .desktop-erp-mod-card.is-wide{ min-height: 208px; }
body.desktop-erp-active .desktop-erp-mod-card.is-wide .desktop-erp-mod-svg,
body.desktop-erp-active .desktop-erp-mod-card.is-wide .desktop-erp-mod-chart,
body.desktop-erp-active .desktop-erp-mod-card.is-wide .desktop-erp-mod-empty{
  min-height: 120px;
  height: 120px;
}

/* Small KPIs under a card title (§3.3: the number leads, the word explains it). */
.desktop-erp-mod-facts{
  display: flex;
  flex-wrap: wrap;
  gap: 6px 22px;
  margin-top: 12px;
}
.desktop-erp-mod-fact{ display: flex; flex-direction: column; gap: 1px; min-width: 74px; }
.desktop-erp-mod-fact-n{
  font-family: var(--font-data);
  font-size: 19px;
  font-weight: 700;
  line-height: 1.1;
  color: var(--light);
}
.desktop-erp-mod-fact-l{
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: #8D8D86;
}

/* Category donut on the Recipes card. */
.desktop-erp-mod-pie{ display: flex; align-items: center; gap: 14px; margin-top: 10px; }
.desktop-erp-mod-pie-legend{ display: flex; flex-direction: column; gap: 3px; min-width: 0; flex: 1; }
.desktop-erp-mod-pie-row{ display: flex; align-items: center; gap: 7px; font-size: 12px; min-width: 0; }
.desktop-erp-mod-pie-dot{ width: 9px; height: 9px; border-radius: 2px; flex: none; }
.desktop-erp-mod-pie-label{
  color: #B5B3AD;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex: 1;
  min-width: 0;
}
.desktop-erp-mod-pie-n{ font-family: var(--font-data); color: var(--light); font-weight: 700; }
/* Check List donut (3. 9. 2026): minutes per section in the legend row, total underneath. */
.desktop-erp-mod-pie-sub{ font-family: var(--font-data); font-size: 11px; color: var(--ink-dim); white-space: nowrap; margin-left: auto; }
.desktop-erp-mod-pie-row .desktop-erp-mod-pie-sub + .desktop-erp-mod-pie-n{ min-width: 1.6em; text-align: right; }
.desktop-erp-mod-pie-foot{
  display: block; margin-top: 5px; padding-top: 5px;
  border-top: 1px solid var(--sand-rule);
  font-family: var(--font-data); font-size: 12px; font-weight: 700; color: var(--light);
}

/* Recipes list, ERP only: the shelf's category mix beside the sections it filters by. The phone
   never gets this — its sticky header is already three rows tall on a 375 px screen. */
.recipe-cat-sticky{ display: none; }
body.desktop-erp-active .recipe-cat-sticky{
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 2px 18px 12px;
  border-top: 1px solid var(--sand-rule);
  margin-top: 2px;
}
body.desktop-erp-active .recipe-cat-sticky-pie{ flex: none; width: 260px; }
body.desktop-erp-active .recipe-cat-sticky-pie .desktop-erp-mod-pie{ margin-top: 8px; }
body.desktop-erp-active .recipe-cat-sticky-chips{
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-content: flex-start;
  flex: 1;
  min-width: 0;
}
.recipe-cat-chip{
  background: var(--sand2);
  border: 1px solid var(--sand-rule);
  border-radius: 999px;
  color: var(--ink-dim);
  cursor: pointer;
  font-size: 12px;
  font-weight: 600;
  padding: 5px 11px;
}
.recipe-cat-chip:hover{ border-color: var(--teal11); color: var(--light); }
.recipe-cat-chip.active{ background: var(--teal11); border-color: var(--teal11); color: var(--on-teal); }
.recipe-cat-chip-n{ font-family: var(--font-data); font-weight: 700; opacity: 0.75; }

/* Ingredient rows on the ERP layout (Richard, 1.9.2026: "oprava veľkých riadkov ingrediencií").
   The phone row is two stacked lines because 375 px cannot hold name, aka, supplier, kcal and
   price side by side. On a 1440 px window that same row was 40 px tall with two thirds of the
   width empty and only thirteen ingredients on screen out of 2 024. One line, four columns. */
body.desktop-erp-active .ingredient-row{
  display: grid;
  grid-template-columns: minmax(190px, 26%) minmax(0, 1fr) auto 18px;
  align-items: center;
  column-gap: 16px;
  padding: 5px 18px;
  min-height: 0;
}
body.desktop-erp-active .ingredient-row .info{ display: contents; }
body.desktop-erp-active .ingredient-row .info .name{
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
body.desktop-erp-active .ingredient-row .info .meta{
  margin-top: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
body.desktop-erp-active .ingredient-row .price{ white-space: nowrap; }

/* Events, ERP layout only (Richard, 1.9.2026, bod 10). Scan and New Event stay reachable while
   the booking list scrolls, and the two panels the wide window has room for sit side by side. */
body.desktop-erp-active #eventsActionRow{
  position: sticky;
  /* The offset is written by renderEvents() from the view header's measured height — the header
     is itself sticky at top:0 with z-index 10, so a hard-coded 0 here parks the buttons
     underneath it and they vanish exactly when they are needed. */
  top: 0;
  z-index: 9;
  background: var(--bg);
  padding: 10px 0;
  margin-top: -10px;
  border-bottom: 1px solid var(--sand-rule);
}
.ev-side-panels{ display: grid; grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr); gap: 12px; margin-top: 14px; }
/* Days with bookings live inline in the contacts list on the ERP layout (3. 9. 2026), so the
   under-graph row is one column; the rail element stays in the DOM, hidden, for the phone. */
body.desktop-erp-active .ev-under-graph-row{
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 12px;
  align-items: start;
}
.ev-contact-list-merged{ max-height: 340px; }
/* doubled class: this block sits before .ev-contact-row in the sheet, so it must outrank it */
.ev-contact-row.ev-contact-row-merged{
  grid-template-columns: 10rem minmax(0, 1.25fr) minmax(0, 1fr);
  gap: 12px;
  padding: 7px 0;
}
.ev-day-chip-inline{ width: 100%; padding: 6px 10px; }
.ev-contact-row-merged:hover .ev-day-chip-inline{ border-color: var(--teal11, #0BD8B6); }
body.desktop-erp-active .ev-under-graph-row #eventsSidePanels{ min-width: 0; }
body.desktop-erp-active #eventsDaySelection{ margin-top: 14px; }
/* Float breaks sticky (Richard, 1.9.2026) — pin Kitchen Figures + Diets while the list scrolls. */
body.desktop-erp-active #eventsView > .desktop-erp-hub-aside{
  float: none;
  position: fixed;
  right: 16px;
  top: calc(var(--erp-topbar-h, 56px) + 12px);
  width: 280px;
  margin: 0;
  z-index: 11;
  max-height: calc(100vh - var(--erp-topbar-h, 56px) - 24px);
  overflow-y: auto;
  box-sizing: border-box;
}
body.desktop-erp-active #eventsView .ev-aside-diets{
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--sand-rule);
}
body.desktop-erp-active #eventsView .ev-aside-diets .section-label{ padding: 0 0 6px; }
body.desktop-erp-active #eventsView .ev-aside-diets .desktop-erp-hub-pie{
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
}
body.desktop-erp-active #eventsView .ev-aside-diets .desktop-erp-hub-pie-svg{
  width: 108px;
  height: 108px;
}
body.desktop-erp-active #eventsView .ev-aside-diets .desktop-erp-hub-pie-legend-row{
  min-height: 36px;
  font-size: 12px;
}
.ev-side-card{
  border: 1px solid var(--sand-rule);
  border-radius: 8px;
  background: var(--sand2);
  padding: 10px 14px 12px;
  min-width: 0;
}
.ev-side-card .section-label{ padding: 0 0 6px; }
.ev-contact-list{ max-height: 260px; overflow-y: auto; }
.ev-contact-row{
  display: grid;
  grid-template-columns: 7.25rem minmax(0, 1fr) minmax(0, 1.1fr);
  align-items: center;
  gap: 10px;
  padding: 6px 0;
  border-top: 1px solid var(--sand-rule);
}
.ev-contact-row:first-child{ border-top: none; }
.ev-contact-when{ font-family: var(--font-data); font-weight: 700; color: var(--light); }
.ev-contact-who{ min-width: 0; overflow: hidden; }
.ev-contact-who b, .ev-contact-who .meta{ display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ev-contact-reach{ display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ev-contact-link{
  color: var(--teal11);
  font-size: 12px;
  text-decoration: none;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ev-contact-link:hover{ text-decoration: underline; }
.ev-day-board{
  display: grid;
  grid-template-columns: minmax(148px, 200px) minmax(0, 1fr);
  gap: 12px;
  align-items: start;
}
.ev-under-graph-row{ display: block; }
.ev-day-rail{
  border: 1px solid var(--sand-rule, #223d57);
  border-radius: 8px;
  background: var(--sand2, #0E2138);
  padding: 10px 10px 12px;
  position: sticky;
  top: 72px;
  max-height: calc(100vh - 120px);
  overflow-y: auto;
}
.ev-day-rail-list{
  display: flex; flex-direction: column; gap: 6px;
}
.ev-day-chip{
  display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
  width: 100%; padding: 10px 12px;
  border-radius: 8px; border: 1px solid var(--sand-rule, #223d57);
  background: #0E2138; color: var(--light, #F5F5F0);
  font: inherit; text-align: left; cursor: pointer;
  -webkit-appearance: none; appearance: none;
}
.ev-day-chip:hover{ border-color: var(--teal11, #0BD8B6); }
@media (max-width: 1023px){
  .ev-day-board{ grid-template-columns: 1fr; }
  .ev-under-graph-row .ev-day-rail{ margin-top: 0; }
  .ev-day-rail{ position: static; max-height: none; }
  .ev-day-rail-list{ flex-direction: row; flex-wrap: wrap; }
  .ev-day-chip{ width: auto; min-width: 7.5rem; }
}
.ev-day-chip.is-on{
  border-color: var(--teal11, #0BD8B6);
  box-shadow: inset 0 0 0 1px var(--teal11, #0BD8B6);
}
.ev-day-chip-when{
  font-family: var(--font-data); font-weight: 700; font-size: 13px; color: var(--teal11, #0BD8B6);
}
.ev-day-chip-meta{ font-size: 11px; color: #8D8D86; }
.ev-beo-kpis{
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 10px;
  margin: 0 0 14px;
}
@media (max-width: 1100px){ .ev-beo-kpis{ grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 640px){ .ev-beo-kpis{ grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.ev-beo-kpi{
  margin: 0;
  padding: 12px 14px;
  border-radius: 8px;
  border: 1px solid #223d57;
  background: #0E2138;
}
.ev-beo-kpi-label{
  font-size: 10px; font-weight: 700; letter-spacing: 0.06em;
  text-transform: uppercase; color: #8D8D86;
}
.ev-beo-kpi-value{
  margin-top: 6px;
  font-family: var(--font-data);
  font-size: 16px; font-weight: 700; color: var(--teal11, #0BD8B6);
  overflow-wrap: anywhere;
}
.ev-diet-pie{ display: flex; justify-content: flex-start; }
.ev-diet-note{ margin-top: 8px; }

/* Ingredient coverage strip (Richard, 1.9.2026, bod 8). Rendered only on the ERP layout, so it
   carries no phone media query — renderIngredientKpiBar() empties the slot below 1024 px. */
.ing-kpi-bar{
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 8px;
  margin: 8px 0 2px;
}
.ing-kpi-cell{
  border: 1px solid var(--sand-rule);
  border-radius: 8px;
  background: var(--sand2);
  padding: 7px 10px;
  min-width: 0;
}
.ing-kpi-label{
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--ink-dim);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ing-kpi-value{
  font-family: var(--font-data);
  font-size: 17px;
  font-weight: 700;
  color: var(--light);
  line-height: 1.2;
}
.ing-kpi-sub{ font-size: 11px; color: var(--ink-dim); white-space: nowrap; }
/* KPI tile as quick filter (3. 9. 2026): off → only → others → off. */
button.ing-kpi-cell.is-filter{
  display: block; width: 100%;
  font: inherit; color: inherit; text-align: left; cursor: pointer;
  -webkit-appearance: none; appearance: none;
}
button.ing-kpi-cell.is-filter:hover{ border-color: var(--teal11, #0BD8B6); }
.ing-kpi-cell.is-only{
  border-color: var(--teal11, #0BD8B6);
  box-shadow: inset 0 0 0 1px var(--teal11, #0BD8B6);
}
.ing-kpi-cell.is-others{
  border-color: var(--copper, #C98A4B);
  border-style: dashed;
  box-shadow: inset 0 0 0 1px var(--copper, #C98A4B);
}
.ing-kpi-state{
  font-size: 10px; text-transform: uppercase; letter-spacing: 0.07em; font-weight: 700;
  color: var(--teal11, #0BD8B6); white-space: nowrap;
}
.ing-kpi-cell.is-others .ing-kpi-state{ color: var(--copper, #C98A4B); }

/* Check List rows on ERP (Richard, 3. 9. 2026): the name at the ingredient list's 18 px, and the
   controls on the SAME line to its right — the desktop has the width the phone's two-line row
   never had. The phone keeps its 44 px targets; here the buttons match the recipe row's 30 px. */
body.desktop-erp-active .prep-item-row{
  display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center;
  column-gap: 16px; padding: 6px 10px;
}
body.desktop-erp-active .prep-line1{ margin-bottom: 0; min-width: 0; }
body.desktop-erp-active .prep-item-name{ font-size: 18px; line-height: 1.3; }
body.desktop-erp-active .prep-item-dish{ font-size: 14px; }
body.desktop-erp-active .prep-line-one{ overflow: visible; padding-bottom: 0; gap: 6px; }
body.desktop-erp-active .prep-line-one .task-status-btn{
  min-height: 30px; min-width: 0; padding: 5px 10px; font-size: 12.5px; flex: none;
}
body.desktop-erp-active .prep-line-one .prep-priority{ min-height: 30px; height: 30px; min-width: 0; width: 54px; padding: 3px 2px; }
body.desktop-erp-active .prep-line-one .prep-dots{ min-width: 30px; padding: 5px 8px; }

/* Components to review (Richard, 1.9.2026: "vedľa seba + review button"). One column on the
   phone, two on the ERP layout — a recipe with fourteen unmatched lines was a full screen of
   scrolling for what is really a punch list. An open assign box spans both columns so its
   suggestion chips and search field keep their width. */
.rc-review-grid{ display: grid; grid-template-columns: minmax(0, 1fr); gap: 8px; }
/* Ticked suggestion in the "i" assign flow (multi-select, db/319) — same tokens as every other
   is-on chip in the app, no new colour. */
.rc-sug-chip.is-on{ background: var(--copper); color: var(--bg); border-color: var(--copper); }
.rc-review-btn{ flex: none; align-self: flex-start; }
body.desktop-erp-active .rc-review-grid{ grid-template-columns: repeat(2, minmax(0, 1fr)); }
body.desktop-erp-active .rc-review-grid .rc-assign-row{
  border: 1px solid var(--sand-rule);
  border-radius: 8px;
  padding: 10px 12px;
}
body.desktop-erp-active .rc-review-grid .rc-assign-row:has(.rc-assign-box[style*="block"]){
  grid-column: 1 / -1;
}

.desktop-erp-hub-aside{ display: none; }
.desktop-erp-hub-layout{ display: block; }
body.desktop-erp-active .desktop-erp-hub-aside{
  display: block;
  float: right;
  width: 280px;
  margin: 8px 20px 16px 12px;
  padding: 12px 14px;
  border: 1px solid var(--sand-rule);
  border-radius: 8px;
  background: var(--sand2);
  box-sizing: border-box;
  position: sticky;
  top: 12px;
}
/* Check List: reserved grid column. Float + later insertBefore was the jump
   (Kitchen Figures starting at the tabs, ending mid-grid). Phone unchanged. */
body.desktop-erp-active #checkListProjectsView > .desktop-erp-hub-layout[data-hub-layout="checkList"]{
  display: grid;
  grid-template-columns: minmax(0, 1fr) 280px;
  column-gap: 16px;
  align-items: start;
  padding: 0 20px 24px;
  box-sizing: border-box;
}
body.desktop-erp-active #checkListProjectsView .desktop-erp-hub-aside[data-hub-aside="checkList"]{
  float: none;
  position: static;
  width: auto;
  margin: 0;
  align-self: start;
}
body.desktop-erp-active #checkListProjectsView .desktop-erp-hub-main .home-grid{
  margin-right: 0;
  margin-left: 0;
}
body.desktop-erp-active .home-grid{ margin-right: 312px; }
/* Vignety dodávateľov (bod 6) držia ten istý pravý okraj ako mriežka poličiek — pravý stĺpec shellu je 312 px. */
body.desktop-erp-active .supplier-ads{ margin: 18px 312px 8px 20px; }
body.desktop-erp-active #workingTimeHubView > .home-grid,
body.desktop-erp-active #settingsView > .home-grid,
body.desktop-erp-active #adminView > .home-grid{ margin-right: 20px; }
body.desktop-erp-active .desktop-erp-hub-kicker{
  margin: 0 0 6px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #64748b;
}
body.desktop-erp-active .desktop-erp-hub-value{
  margin: 0 0 4px;
  font-family: var(--font-data);
  font-size: 22px;
  font-weight: 700;
  color: var(--light);
}
body.desktop-erp-active .desktop-erp-hub-caption{
  margin: 0 0 10px;
  font-size: 12px;
  color: #8D8D86;
}
body.desktop-erp-active .desktop-erp-hub-list{
  list-style: none;
  margin: 0 0 10px;
  padding: 0;
}
body.desktop-erp-active .desktop-erp-hub-list li{
  display: flex;
  justify-content: space-between;
  gap: 8px;
  padding: 4px 0;
  border-bottom: 1px solid var(--sand-rule);
  font-size: 12px;
  color: var(--light);
}
body.desktop-erp-active .desktop-erp-hub-list .meta{ color: #8D8D86; flex: none; }
body.desktop-erp-active .desktop-erp-hub-empty{
  display: block;
  color: #8D8D86;
  font-size: 18px;
  font-weight: 700;
  text-align: center;
  padding: 8px 0;
}
body.desktop-erp-active .desktop-erp-hub-svg{ display: block; width: 100%; height: 40px; }
/* Current-state graph under the hub tiles. Phone stays the tile grid only. */
.desktop-erp-hub-current{ display: none; }
body.desktop-erp-active .desktop-erp-hub-current{
  display: block;
  margin: 12px 312px 28px 20px;
  min-height: calc(100vh - 300px);
  padding: 16px 18px 20px;
  border: 1px solid var(--sand-rule);
  border-radius: 8px;
  background: var(--sand2);
  box-sizing: border-box;
}
body.desktop-erp-active #checkListProjectsView .desktop-erp-hub-current[data-hub-current="checkList"]{
  margin: 12px 0 0;
  min-height: 0;
  padding: 12px 0 0;
  border: none;
  border-top: 1px solid var(--sand-rule);
  border-radius: 0;
  background: transparent;
}
body.desktop-erp-active .desktop-erp-hub-current-title{
  margin: 0 0 6px;
  font-size: 16px;
  font-weight: 700;
  color: var(--light);
}
body.desktop-erp-active .desktop-erp-hub-current-svg{
  display: block;
  width: 100%;
  height: auto;
  min-height: 88px;
}
body.desktop-erp-active .desktop-erp-hub-current-empty{
  display: block;
  color: #8D8D86;
  font-size: 22px;
  font-weight: 700;
  text-align: center;
  padding: 16px 0 8px;
}
.desktop-erp-hub-kpi{ display: none; }
body.desktop-erp-active .desktop-erp-hub-kpi{
  display: block;
  margin: 12px 0 0;
  padding: 16px 18px 20px;
  border: 1px solid var(--sand-rule);
  border-radius: 8px;
  background: var(--sand2);
  box-sizing: border-box;
}
body.desktop-erp-active .desktop-erp-hub-current-charts{
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  align-items: flex-start;
}
body.desktop-erp-active .desktop-erp-hub-current-pie{
  flex: 0 1 280px;
  min-width: 200px;
}
body.desktop-erp-active .desktop-erp-hub-current-bars{
  flex: 1 1 280px;
  min-width: 200px;
}
body.desktop-erp-active .desktop-erp-hub-pie{
  display: flex;
  gap: 14px;
  align-items: center;
}
body.desktop-erp-active .desktop-erp-hub-pie-svg{
  flex: none;
  width: 132px;
  height: 132px;
}
/* The number in the middle of the donut. A class, not style="font-family:…" in the SVG —
   appearance belongs here (inline_style_guard, 16. 8.). */
.desktop-erp-hub-pie-total{ font-family: var(--font-data); }
body.desktop-erp-active .desktop-erp-hub-pie-legend{
  list-style: none;
  margin: 0;
  padding: 0;
  min-width: 0;
  flex: 1;
}
body.desktop-erp-active .desktop-erp-hub-pie-legend-row{
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding: 4px 0;
  border-bottom: 1px solid var(--sand-rule);
  font-size: 13px;
  color: var(--light);
}
body.desktop-erp-active .desktop-erp-hub-pie-swatch{
  width: 10px;
  height: 10px;
  border-radius: 3px;
  flex: none;
}
body.desktop-erp-active .desktop-erp-hub-pie-label{
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex: 1;
}
body.desktop-erp-active .desktop-erp-hub-pie-n{
  flex: none;
  font-variant-numeric: tabular-nums;
  color: #8D8D86;
}
body.desktop-erp-active #checkListProjectsView .desktop-erp-hub-aside .desktop-erp-hub-pie{
  flex-wrap: wrap;
}
body.desktop-erp-active #checkListProjectsView .desktop-erp-hub-aside .desktop-erp-hub-current-charts{
  flex-direction: column;
}
body.desktop-erp-active #chefAssistantView{
  left: var(--desktop-erp-sidebar-w);
}
body.desktop-erp-active #chefAssistantView > .desktop-erp-hub-aside{
  float: none;
  position: absolute;
  right: 16px;
  top: 88px;
  margin: 0;
}
body.desktop-erp-active #chefAssistantView > .chef-chat-messages{
  max-width: 56rem;
  margin: 0 auto;
  width: 100%;
  box-sizing: border-box;
  padding-right: 312px;
}
body.desktop-erp-active .chef-msg{ max-width: 36rem; }
body.desktop-erp-active #eventsView .wrap{ max-width: none; padding: 12px 20px 32px; margin-right: 312px; }
/* ERP: the load chart is a compact sticky strip (Richard, 3. 9. 2026: „sticky graf, menší") —
   the bookings scroll under it and a tapped bar's list stays within reach. */
body.desktop-erp-active #eventsView .ev-chart-card{
  /* Third band of the sticky stack: .topbar (top 0, 116 high) → #eventsActionRow (top 116,
     65 high) → this card at 181. Offsets count from under the fixed bar, because body is the ERP
     scroller and carries the bar as padding-top (measured 3. 9. 2026). */
  position: sticky; top: 181px; z-index: 8;
  margin-top: 10px; box-shadow: 0 10px 22px rgba(0, 0, 0, 0.35);
}
/* the two-line legend moves into the nav line on ERP (see renderEventsChart), so the card stays ~200 px */
body.desktop-erp-active #eventsView .ev-chart-card .u-t-tac-mt2{ display: none; }
body.desktop-erp-active #eventsView .ev-chart-card #eventsChartBody{ padding: 0 10px 6px; }
/* the collapse toggle is a phone affordance; on ERP the nav line carries the summary instead */
body.desktop-erp-active #eventsView .ev-chart-card #eventsChartToggle{ display: none; }
body.desktop-erp-active #eventsView .ev-chart-card .sheet-row{ margin: 4px 0 2px; }
body.desktop-erp-active #eventsView .ev-chart-card .meta{ font-size: 11px; }
body.desktop-erp-active #listView .recipe-row{ padding: 8px 20px; }
@media (max-width: 1180px){
  body.desktop-erp-active .desktop-erp-hub-aside{
    float: none;
    width: auto;
    position: static;
    margin: 8px 20px 12px;
  }
  body.desktop-erp-active .home-grid{ margin-right: 0; }
  body.desktop-erp-active .supplier-ads{ margin-right: 0; }
  body.desktop-erp-active .desktop-erp-hub-current{ margin: 8px 20px 20px; }
  body.desktop-erp-active #eventsView .wrap{ margin-right: 0; }
  body.desktop-erp-active #eventsView > .desktop-erp-hub-aside{
    position: static;
    right: auto;
    width: auto;
    max-height: none;
    margin: 8px 20px 12px;
  }
  body.desktop-erp-active #chefAssistantView > .chef-chat-messages{ padding-right: 18px; }
  body.desktop-erp-active #chefAssistantView > .desktop-erp-hub-aside{
    position: static;
    margin: 8px 20px 12px;
  }
  body.desktop-erp-active #checkListProjectsView > .desktop-erp-hub-layout[data-hub-layout="checkList"]{
    grid-template-columns: minmax(0, 1fr);
  }
  body.desktop-erp-active #checkListProjectsView .desktop-erp-hub-current[data-hub-current="checkList"]{
    margin: 12px 0 0;
  }
}

/* F9.demo — global toggle + full-width amber banner (FINALNY_PROMPT §4).

   FIXED, not sticky (31. 8. 2026). `position: sticky` on the LAST child of <body> only reaches
   its `top: 0` anchor once the page has scrolled past that child's own place in the flow — and
   being last, that place is the bottom of the document. Measured on a 932 px phone viewport:
   the bar sat at y=2068 on Home, y=2002 on Check List, y=767 on Settings. The banner whose
   whole job is to say the numbers on screen are not real was below the fold on every screen
   that had content. The single screen where it did show is the one where the body's flow
   collapses because the view is itself `position: fixed` — Chef's Assistant — and there it
   landed at y=58, directly on that screen's own title. One cause, two symptoms.

   The nav band above it is fixed at 58 px, so the chrome sits just under it; body's padding
   reserves the height, and because body is this app's scroll container that same padding
   re-anchors every per-view sticky topbar below the chrome. Identical mechanism to the one
   `body.has-floating-nav` already uses for the band. */
.sautero-global-demo-chrome {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 9000;
  width: 100%;
}
body.has-floating-nav .sautero-global-demo-chrome { top: 58px; }
/* Chef's Assistant hides the nav band, so nothing sits above the chrome there. */
body.chef-chat-open .sautero-global-demo-chrome { top: 0; }
.sautero-global-demo-toggle-row {
  display: flex;
  justify-content: flex-end;
  padding: 6px 10px 0;
  pointer-events: none;
}
.sautero-global-demo-toggle {
  pointer-events: auto;
  min-height: 36px;
  padding: 6px 12px;
  border-radius: 8px;
  border: 1.5px solid var(--amber);
  background: rgba(17, 17, 16, 0.92);
  color: var(--amber-text);
  font-weight: 700;
  font-size: 12px;
  cursor: pointer;
}
.sautero-global-demo-toggle.active {
  background: var(--amber);
  color: var(--on-amber);
}
.sautero-global-demo-banner {
  width: 100%;
  background: var(--amber);
  color: var(--on-amber);
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 0.02em;
  text-align: center;
  padding: 10px 14px;
  margin-top: 6px;
}
.sautero-demo-row-mark {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 6px;
  border-radius: 4px;
  background: var(--amber);
  color: var(--on-amber);
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.04em;
  vertical-align: middle;
}
body.sautero-demo-on .sautero-global-demo-chrome {
  box-shadow: 0 1px 0 rgba(17, 17, 16, 0.08);
}
/* Kolo 23 (Richard 7. 9. 2026): na telefone je z ramu IKONA — 46 px kruh v pravom dolnom rohu, zrkadlo
   tlacidla spatnej vazby vlavo. Vyssia specificita (3 triedy) prebije `top: 58px` pri has-floating-nav aj
   `top: 0` pri chef-chat-open; z-index klesa pod plachty, aby ikona nesedela nad otvorenym harkom. */
body.surface-mobile .sautero-global-demo-chrome.sautero-demo-fab {
  top: auto;
  left: auto;
  right: 16px;
  bottom: 22px;
  width: auto;
  z-index: 36;
}
body.surface-mobile.has-mobile-nav .sautero-global-demo-chrome.sautero-demo-fab {
  bottom: calc(22px + 64px + env(safe-area-inset-bottom, 0px));
}
/* Asistent je celoobrazovkový fixed pohľad a ikona by sedela na tlačidle Send — rovnaké pravidlo
   ako má bublina spätnej väzby. Ovládač demo drží ⚙️ ponuka a lišta Home. */
body.chef-chat-open .sautero-global-demo-chrome.sautero-demo-fab { display: none !important; }
.sautero-global-demo-fab-btn {
  width: 46px;
  height: 46px;
  border-radius: 50%;
  border: 1.5px solid var(--amber);
  background: var(--paper-raised, var(--paper));
  color: var(--ink);
  font-size: 20px;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.32);
  cursor: pointer;
}
.sautero-global-demo-fab-btn.active {
  background: var(--amber);
  color: var(--on-amber);
}
/* ERP sidebar sparklines (ops_hub.js). The Check List ops hub cards that stood here were removed
   with the hub itself (4. 9. 2026, screen A of the desktop brief replaces Stations/Stock/Analytics). */
.ops-hub-spark-empty { color: #8D8D86; font-size: 13px; }
.ops-hub-spark { display: block; }
.desktop-erp-nav-spark { flex: none; width: 48px; height: 16px; display: flex; align-items: center; justify-content: flex-end; }
.desktop-erp-nav-spark-empty { color: #64748b; font-size: 12px; }
body.desktop-erp-active .sheet-handle { display: none; }
#desktopErpInlineHost.desktop-erp-inline-host {
  display: none;
  padding: 16px 28px 40px;
  min-height: 100%;
  box-sizing: border-box;
}
.desktop-erp-inline-bar {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  margin: 0 0 16px;
}
.desktop-erp-crumb {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin: 0;
  font-size: 13px;
  color: #8D8D86;
  flex: 1;
}
.desktop-erp-inline-close {
  background: none;
  border: 1px solid #334155;
  color: #e2e8f0;
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  padding: 6px 12px;
  border-radius: 8px;
  flex: none;
}
.desktop-erp-crumb-link {
  background: none;
  border: none;
  color: var(--teal11);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
  padding: 0;
}
.desktop-erp-crumb-sep { color: #64748b; }
.desktop-erp-crumb-current { color: var(--light); font-weight: 600; }
#desktopErpInlineSlot .sheet,
.desktop-erp-inline-sheet.sheet {
  position: static;
  max-width: none;
  width: 100%;
  max-height: none;
  border-radius: 0;
  border: none;
  background: transparent;
  padding: 0 0 24px;
  overflow: visible;
  box-shadow: none;
}
/* injectSheetCloseButtons() prepends a ✕ to every sheet that can be dismissed by tapping the
   backdrop — it IS that tap, for a thumb. An inlined sheet has no backdrop and already sits
   under the inline bar's Close, so the ✕ is a second exit for one action (Richard, 1. 9. 2026:
   the merged AI screen had three). Phone path untouched: this only matches inside the ERP host. */
.desktop-erp-inline-sheet .sheet-x { display: none; }

/* KPI strip shared by the merged AI screen and the Error Logs charts. Same card shape as the
   ERP Home facts so an admin screen does not look like a different product. */
.ai-kpi-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 10px;
  margin: 10px 0 4px;
}
.ai-kpi-card {
  background: var(--paper-raised);
  border: 1px solid var(--card-rule);
  border-radius: 12px;
  padding: 10px 12px;
  min-width: 0;
}
.ai-kpi-label {
  font-size: 10.5px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: 4px;
}
.ai-kpi-value {
  font-family: var(--font-data);
  font-size: 22px;
  font-weight: 700;
  color: var(--ink);
  line-height: 1.1;
  overflow-wrap: anywhere;
}
.ai-kpi-sub { font-size: 11px; color: var(--ink-dim); margin-top: 3px; }
.ai-kpi-chart { width: 100%; height: 90px; display: block; }
/* Donut KPI on AI Usage & Error Logs — same krDonut markup as recipe/report pies; this wrap
   only gives the section a stable host so the legend does not collide with the bar chart. */
.ai-kpi-donut { margin: 4px 0 10px; max-width: 520px; }
.ai-kpi-kind {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}
.ai-kpi-kind-bar {
  height: 8px;
  border-radius: 4px;
  background: var(--teal9);
  flex: 0 0 auto;
}
/* DB row points at a photo that is gone from storage — labelled placeholder, never a broken icon. */
.recipe-photo-missing{
  display:flex;
  align-items:center;
  justify-content:center;
  text-align:center;
  box-sizing:border-box;
  background:var(--sand1);
  color:var(--teal11);
  font-size:11px;
  font-weight:700;
  letter-spacing:.02em;
  line-height:1.3;
  padding:6px;
}
.recipe-photo-missing--form{
  flex:none;
  width:56px;
  height:56px;
  border-radius:8px;
  border:1px solid var(--rule);
  font-size:10px;
}
.recipe-photo-missing-admin{
  margin:0 0 12px;
  padding:10px 12px;
  border-radius:8px;
  background:var(--sand1);
  color:var(--teal11);
  font-size:13px;
  font-weight:600;
}

.price-source-badge{
  display: inline-block;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.02em;
  line-height: 1.2;
  padding: 2px 7px;
  border-radius: 999px;
  margin-left: 6px;
  vertical-align: middle;
  white-space: normal;
  max-width: none;
}
.price-source-estimate{
  background: rgba(229, 72, 77, 0.18);
  border: 1px solid var(--red);
  color: var(--red-text);
}
.price-source-verified{
  background: rgba(11, 216, 182, 0.16);
  border: 1px solid var(--teal11);
  color: var(--copper);
}
.price-source-listed{
  background: rgba(74, 144, 226, 0.14);
  border: 1px solid #4a90e2;
  color: #2a5f9e;
  font-weight: 500;
}
.price-source-manual{
  background: rgba(141, 141, 134, 0.14);
  border: 1px solid #8D8D86;
  color: #6b6570;
  font-weight: 500;
}
.price-source-stale{
  background: rgba(230, 184, 77, 0.16);
  border: 1px solid #e6b84d;
  color: #c4921a;
}

/* JS šablóny — dávka 1 (28. 8. 2026). 16 atribútov, výhradne absolútne hodnoty
   (px / farba / kľúčové slovo). Dôkaz: template_style_proof (ekvivalencia deklarácií,
   NIE špecificita v appke — viď hlavičku nástroja). display:none, %, auto, inherit, em,
   pending/ REZ kópie a SVG do tejto dávky nepatria. */
.u-t-op06{opacity:.6;}
.u-t-c888{color:#888;}
.u-t-my7{margin:7px 0;}
.u-t-fww{flex-wrap:wrap;}
.u-t-py6{padding:6px 0;}
.u-t-py14{padding:14px 0;}
.u-t-py10{padding:10px 0;}
.u-t-fw700-mb2{font-weight:700; margin-bottom:2px;}
.u-t-tac-mt2{text-align:center; margin-top:2px;}
.u-t-fnone-fw700{flex:none; font-weight:700;}
.u-t-mt6-op07{margin:6px 0 0 0; opacity:.7;}
.u-t-ink-mt5{color:var(--ink); margin-top:5px;}
.u-t-op06-mt6{opacity:.6; margin-top:6px;}
.u-t-flex1-minw0-lh135{flex:1; min-width:0; line-height:1.35;}
.u-t-my6-aic{margin:6px 0 2px 0; align-items:center;}
.u-t-nowrap-as-cop-fw700{white-space:nowrap; align-self:center; color:var(--copper); font-weight:700;}

/* JS šablóny — dávka 2 (29. 8. 2026). Ďalších 16 absolútnych. Rovnaké pravidlá ako dávka 1. */
.u-t-c777{color:#777;}
.u-t-fs19{font-size:19px;}
.u-t-fs18-lh12-mb2{font-size:18px; line-height:1.2; margin-bottom:2px;}
.u-t-cinkdim-mt4{color:var(--ink-dim); margin-top:4px;}
.u-t-mb4{margin-bottom:4px;}
.u-t-mt8-i{margin-top:8px; font-style:italic;}
.u-t-py40-cfaint-tac{padding:40px 18px; color:var(--ink-faint); text-align:center;}
.u-t-op065-mb10{opacity:.65; margin-bottom:10px;}
.u-t-op075{opacity:.75;}
.u-t-ccop-fw700{color:var(--copper); font-weight:700;}
.u-t-strike-cdim{text-decoration:line-through; color:var(--ink-dim);}
.u-t-mt4-mb0{margin-top:4px; margin-bottom:0;}
.u-t-ccop-tdn{color:var(--copper); text-decoration:none;}
.u-t-cfaint-fs135{color:var(--ink-faint); font-size:13.5px;}
.u-t-op085{opacity:0.85;}
.u-t-mtn14-mb20{margin:-14px 0 20px 0;}

/* kitchen-a11y-floor-icon: 44x44 wet-thumb. Do not delete. */
.icon-btn, .fav-star, .back-btn, .row-remove, .cost-info-btn, .sheet-x,
.qa-checkbox, .prep-line-one .prep-dots, .prep-line-one .prep-act-btn,
.prep-line-one .prep-priority, .floating-nav .fn-buttons button,
.global-feedback-btn, .fab, .task-status-btn{
  min-width: 44px;
  min-height: 44px;
  box-sizing: border-box;
}
/* kitchen-a11y-floor-text: 44px min-height wet-thumb. Do not delete. */
.save-btn, .chip, .task-status-btn, .chef-chat-send, .chef-save-recipe,
.add-row-btn, .danger-btn, .lang-switch, .mode-toggle-center,
.search-action-btn, .icon-choice-btn, .prep-filter-toggle, .sheet-cancel,
.sheet-option, .link-btn, .form-field, .prep-input, .qa-qty-input,
.qa-priority, .more-details summary, .all-station-strip-row,
.prep-duplicate-badge{
  min-height: 44px;
  box-sizing: border-box;
}
/* kitchen-a11y-ios-zoom: form controls stay >=16px. Do not delete. */
.step-row textarea, .lang-switch{ font-size:16px; }

/* kitchen-layout-44-rows: 44px floor must wrap, not overlap. Do not delete.
   Úloha 24 set min 44×44 on .cost-info-btn / .icon-btn / .chef-save-recipe.
   Those rules stay. Recipe table uses a grid so 44px buttons do not overlap
   qty. Ingredient rows stay one flex line (name+meta | price+badge) so the
   list shows as many items as a 390px phone can. This block does not shrink
   a tap target. */
table.ing td{
  vertical-align: middle;
  padding: 14px 0;
}
table.ing td:first-child{
  display: grid;
  grid-template-columns: minmax(0, 1fr) 44px 44px;
  align-items: center;
  column-gap: 6px;
}
table.ing td:first-child > .cost-info-btn{ justify-self: center; }
table.ing td.qty{
  white-space: nowrap;
  vertical-align: middle;
  width: 1%;
  padding-left: 10px;
}
/* 44px tap, 18px visible circle — the floor stays, the painted disc does not
   eat the row. */
table.ing .cost-info-btn,
.cost-block .cost-info-btn{
  width: 44px;
  height: 44px;
  border: none;
  border-radius: 0;
  background: transparent;
  font-size: 13px;
  position: relative;
}
table.ing .cost-info-btn::before,
.cost-block .cost-info-btn::before{
  content: '';
  position: absolute;
  inset: 12px;
  border: 1px solid var(--ink-dim);
  border-radius: 50%;
  pointer-events: none;
}
.cost-block .label{
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0 4px;
}
.cost-block .label > .cost-info-btn{ flex: none; }
.cost-item .value{
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 8px;
}
.scale-advanced, .scale-bar{
  overflow: visible;
  padding: 14px 12px;
}
.scale-input, .scale-select{
  min-height: 44px;
  font-size: 16px;
}
.ingredient-row{
  align-items: center;
  flex-wrap: nowrap;
  gap: 10px;
  padding: 8px 14px;
}
.ingredient-row .info{
  flex: 1 1 auto;
  min-width: 0;
}
.ingredient-row .name{
  display: block;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ingredient-row .meta{
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ingredient-row .price{
  flex: none;
  min-width: max-content;
  max-width: none;
  display: inline-flex;
  flex-wrap: nowrap;
  align-items: center;
  justify-content: flex-end;
  gap: 4px;
  text-align: right;
  white-space: nowrap;
}
.ingredient-row .price .price-source-badge{
  margin-left: 0;
  flex: none;
}
.ingredient-row .price .price-source-estimate{
  font-size: 0;
  width: 16px;
  min-width: 16px;
  height: 16px;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.ingredient-row .price .price-source-estimate::after{
  content: '!';
  font-size: 11px;
  font-weight: 800;
  line-height: 1;
}
.ingredient-row .chevron{
  align-self: center;
  margin-top: 0;
}
#priceHistoryTitle{
  overflow-wrap: anywhere;
  white-space: normal;
}
.chef-msg{ padding: 12px 14px; }
.chef-save-recipe{ margin-top: 12px; padding: 8px 2px; }
.chef-chat-input-bar{ align-items: stretch; }
.chef-chat-input{ min-height: 44px; }
.chef-chat-send{
  display: flex;
  align-items: center;
  height: 44px;
}
/* Reserved Check List title slot (icon + text). Swapping Check List ↔ Stations
   must not move the page. Font, size and the clipboard glyph stay the same —
   only the row height is reserved. Do not restyle .title.display here. */
#checkListProjectsView h1.title.display,
#tasksView h1.title.display{
  min-height: 1.2em;
}

/* ══════════════════════════════════════════════════════════════════════════════════════════
   VISUAL v2 — components from the style-guide mockups (Richard, 31. 8. 2026)

   Appended as one self-contained block (single-file-surgeon: additive-first). Nothing above
   this line was reordered; the palette change lives in :root and in the 208 remapped literals.
   Swatches sampled from the guide image itself: sand1 #111110, sand2 #191918, teal9 #12A594,
   teal11 #0BD8B6, amber #FFC53D, red #E5484D, ok-green #30A46C, light #FDFDFC.
   ══════════════════════════════════════════════════════════════════════════════════════════ */

/* ── Two-tone wordmark ──────────────────────────────────────────────────────────────────────
   "Saut" in --ink, "ero" in --copper (teal11), Fraunces. The guide shows this on every
   surface, so it is one class rather than a per-screen span colour: a wordmark that is
   hand-coloured at four call sites is a wordmark that will be three colours by next month. */
/* ZADANIE §2.4a. Fraunces 700, tracking -1.1px — expressed as -0.025em because the same
   wordmark is drawn at seven sizes here (44px hero down to the 13px floating-nav label) and an
   absolute -1.1px, which is what the guide measured on its 44px specimen, would weld the
   letters together on the small ones. Below 16px the guide drops the lettering entirely and
   uses the teal tile alone; .brand-logo-min enforces that floor. */
.brand-logo{
  font-family: var(--font-brand);
  font-weight: 700;
  letter-spacing: -0.025em;
  color: var(--ink);
}
.brand-logo > i,
.brand-logo > .brand-logo-tail{
  font-style: normal;
  color: var(--copper);
}
.brand-logo-19{ font-size: 19px; }
/* On the teal surface the word is one colour and is not split (guide table, row 3). */
.brand-on-teal .brand-logo,
.brand-on-teal .brand-logo > i{ color: #04231F; }

/* ── Status pill: colour is never the only channel (dot + word), per the guide caption
   "Status nie nur über Farbe — auch Text und Icon". ─────────────────────────────────────── */
.v2-pill{
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex: none;
  padding: 5px 11px;
  border-radius: 999px;
  border: 1px solid var(--rule);
  background: var(--paper-raised);
  color: var(--ink-dim);
  font-family: var(--font-ui);
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
}
.v2-pill::before{
  content: '';
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: currentColor;
  flex: none;
}
.v2-pill.ok{ color: var(--ok-green-text); }
.v2-pill.open{ color: var(--amber-text); }
.v2-pill.now{ color: var(--red-text); }
.v2-pill.info{ color: var(--copper); }
/* Measured on the live ERP table, 31. 8.: the three status colours clear AA on white
   (4.72 / 4.61 / 4.61) and FAIL on the raised chip (4.14 / 4.01 / 4.05), because --paper-raised
   is #F1F0EF in the light theme. The chip keeps its hairline, so it still reads as a chip. */
:root[data-theme="light"] .v2-pill{ background: var(--paper); }

/* ── KPI card (Erledigt / Offen / Kritisch, Positionen / Unter Minimum / Wert) ───────────── */
/* minmax(108px) so the three Check List cards stay on ONE row on a 430px phone the way the
   guide shows them, instead of orphaning "Kritisch" onto a second row. */
.v2-kpis{
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(108px, 1fr));
  gap: 12px;
  margin: 0 0 16px;
}
.v2-kpi{
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: 14px;
  padding: 14px 16px 16px;
  min-width: 0;
}
.v2-kpi .v2-kpi-label{
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 500;
  color: var(--ink-dim);
  margin: 0 0 6px;
}
.v2-kpi .v2-kpi-value{
  font-family: var(--font-data);
  font-weight: 700;
  font-size: 30px;
  line-height: 1.05;
  color: var(--ink);
  display: flex;
  align-items: baseline;
  gap: 4px;
}
.v2-kpi .v2-kpi-unit{
  font-size: 14px;
  font-weight: 400;
  color: var(--ink-dim);
}
.v2-kpi .v2-kpi-foot{
  font-family: var(--font-ui);
  font-size: 12px;
  color: var(--ink-dim);
  margin: 8px 0 0;
}
.v2-kpi.teal .v2-kpi-value{ color: var(--copper); }
.v2-kpi.amber .v2-kpi-value{ color: var(--amber-text); }
.v2-kpi.red .v2-kpi-value{ color: var(--red-text); }

/* ── Big touch row (wet hands: 64px min target, checkbox 30px) ───────────────────────────── */
.v2-rows{ display: flex; flex-direction: column; gap: 10px; }
.v2-row{
  display: flex;
  align-items: center;
  gap: 14px;
  min-height: 64px;
  padding: 12px 16px;
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: 14px;
}
.v2-row-box{
  flex: none;
  width: 30px;
  height: 30px;
  border-radius: 8px;
  border: 2px solid var(--rule);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
  line-height: 1;
  color: transparent;
}
.v2-row.done .v2-row-box{
  background: var(--teal9);
  border-color: var(--copper);
  color: #111110;
  font-weight: 800;
}
.v2-row-body{ flex: 1; min-width: 0; }
.v2-row-title{
  display: block;
  font-family: var(--font-ui);
  font-size: 15px;
  font-weight: 600;
  color: var(--ink);
  overflow-wrap: anywhere;
}
.v2-row.done .v2-row-title{ color: var(--ink-dim); }
.v2-row-sub{
  display: block;
  font-family: var(--font-ui);
  font-size: 12.5px;
  color: var(--ink-dim);
  margin-top: 2px;
  overflow-wrap: anywhere;
}
.v2-row-time{
  font-family: var(--font-data);
  font-size: 14px;
  font-weight: 700;
  color: var(--ink-dim);
  flex: none;
}
.v2-row-right{ display: flex; align-items: center; gap: 10px; flex: none; }

/* ── Heute panel (mobile Home header, guide image "Guten Abend, Küche.") ─────────────────── */
/* The gutter matches .home-grid (18px) — the panel is a sibling of the grid inside #homeView,
   which has no padding of its own, so without this the cards run off the right edge. */
#sauteroHeutePanel:not(:empty),
#sauteroChecklistV2Host:not(:empty){
  display: block;
  padding: 10px 18px 0;
}
.v2-heute{
  margin: 0 0 18px;
  max-width: 720px;
}
.v2-heute-kicker{
  font-family: var(--font-ui);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-dim);
  margin: 0 0 6px;
}
.v2-heute-title{
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 30px;
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--ink);
  margin: 0 0 6px;
}
.v2-heute-lede{
  font-family: var(--font-ui);
  font-size: 13.5px;
  line-height: 1.45;
  color: var(--ink-dim);
  margin: 0 0 16px;
}
.v2-heute-metrics{
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  margin: 0 0 14px;
}
/* Phone Home summary line (INVESTOR_PROTO FÁZA 2): one row, two words and a number. */
.v2-heute-line{
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin: 0 0 14px;
  padding: 10px 14px;
  border-radius: 12px;
  border: 1px solid var(--sand-rule);
  background: var(--sand2);
  font-family: var(--font-ui);
  font-size: 13.5px;
  color: var(--ink-dim);
}
.v2-heute-line b{ font-size: 20px; color: var(--teal11); font-weight: 700; }
.v2-shift-pill{
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 7px 14px;
  border-radius: 999px;
  border: 1px solid var(--copper);
  background: rgba(11,216,182,0.10);
  color: var(--copper);
  font-family: var(--font-ui);
  font-size: 12.5px;
  font-weight: 600;
}
.v2-heute-head{
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin: 0 0 8px;
}
.v2-heute-head .v2-heute-kicker{ margin: 0; }

/* ── Chart card (food-cost trend, station donut) ─────────────────────────────────────────── */
.v2-chart-card{
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: 14px;
  padding: 14px 16px 10px;
  margin: 0 0 14px;
  min-width: 0;
}
.v2-chart-head{
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  margin: 0 0 10px;
}
.v2-chart-title{
  font-family: var(--font-ui);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-dim);
}
/* §3.3: text never wears a series colour. The default note is plain secondary text; the two
   toned variants are STATUS (which way it moved and whether that is good), not identity. */
.v2-chart-note{
  font-family: var(--font-ui);
  font-size: 12px;
  color: var(--ink-dim);
  font-weight: 600;
}
.v2-chart-note.good{ color: var(--ok-green-text); }
.v2-chart-note.bad{ color: var(--red-text); }
.v2-chart-card svg{ display: block; width: 100%; height: auto; }
.v2-legend{
  display: flex;
  flex-wrap: wrap;
  gap: 6px 14px;
  margin: 10px 0 4px;
  font-family: var(--font-ui);
  font-size: 11.5px;
  color: var(--ink-dim);
}
.v2-legend span{ display: inline-flex; align-items: center; gap: 6px; }
.v2-legend i{ width: 9px; height: 9px; border-radius: 3px; display: inline-block; font-style: normal; }
/* One class per chart colour, so a legend swatch never needs style="background:…" in the
   markup (inline_style_guard, 16. 8.). The hexes are the same V2_CHART_COLORS that heute.js
   draws with — visual_v2_check keeps the two lists identical. The first five are the series,
   in the order ZADANIE §3.1 fixes; amber/red/green are status and never a series. */
.v2-sw-teal  { background: #12A594; }
.v2-sw-indigo{ background: #3E63DD; }
.v2-sw-pink  { background: #D6409F; }
.v2-sw-cyan  { background: #00A2C7; }
.v2-sw-plum  { background: #AB4ABA; }
.v2-sw-amber { background: #FFC53D; }
.v2-sw-red   { background: #E5484D; }
.v2-sw-green { background: #30A46C; }
.v2-sw-grid  { background: #3B3A37; }
.v2-sw-muted { background: #B5B3AD; }
.v2-sw-ink   { background: #EEEEEC; }
.v2-sw-paper { background: #191918; }

/* Every chart's table view (§3.1 / G-CHART-3). A <details> so the numbers are one tap away
   rather than doubling the height of a dashboard, but present on every chart without
   exception — in light mode teal reads at 2.92 : 1 and cyan at 2.85 : 1 against the section
   background, so colour alone cannot be the only way to a value. */
.v2-chart-table{
  margin: 10px 0 2px;
  border-top: 1px solid var(--rule);
  padding-top: 8px;
}
.v2-chart-table > summary{
  font-family: var(--font-ui);
  font-size: 11.5px;
  font-weight: 600;
  color: var(--ink-dim);
  cursor: pointer;
  list-style: none;
  padding: 4px 0;
  min-height: 24px;
}
.v2-chart-table > summary::-webkit-details-marker{ display: none; }
.v2-chart-table > summary::before{ content: '▸ '; }
.v2-chart-table[open] > summary::before{ content: '▾ '; }
.v2-chart-table .v2-table{ margin-top: 6px; }

/* ── Stock / alert list (Lager mockup) ───────────────────────────────────────────────────── */
.v2-table{
  width: 100%;
  border-collapse: collapse;
  font-family: var(--font-ui);
  font-size: 13px;
}
.v2-table th{
  text-align: left;
  font-weight: 600;
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-dim);
  padding: 0 10px 8px 0;
  border-bottom: 1px solid var(--rule);
}
.v2-table td{
  padding: 11px 10px 11px 0;
  border-bottom: 1px solid var(--rule);
  color: var(--ink);
  vertical-align: middle;
}
.v2-table td.num{ font-family: var(--font-data); text-align: right; }
.v2-table th.num{ text-align: right; }

@media (max-width: 430px){
  .v2-heute-title{ font-size: 26px; }
  .v2-kpi .v2-kpi-value{ font-size: 26px; }
}

/* Extra v2 bits used by js/heute.js — compact row, inline progress bar, donut wrapper,
   dashboard grid, section title. Kept out of the inline style attributes so the CSP stays
   as it is and so a colour change is one edit, not twenty template literals. */
.v2-row-compact{ min-height: 54px; }
.v2-row-icon{
  flex: none;
  width: 30px;
  text-align: center;
  font-size: 17px;
  line-height: 1;
}
.v2-bar{
  display: block;
  height: 6px;
  border-radius: 99px;
  background: var(--rule);
  margin-top: 8px;
  overflow: hidden;
}
.v2-bar-fill{ display: block; height: 6px; border-radius: 99px; }
/* The donut has its own intrinsic 180px box; without this it inherits the chart card's
   width:100% rule and blows up to the full card width. */
.v2-donut-wrap{ display: flex; justify-content: center; }
.v2-donut-wrap svg{ width: 180px; height: 180px; flex: none; }
.v2-section-title{ display: block; margin: 18px 0 10px; }
.v2-dash-grid{
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 14px;
  align-items: start;
}

/* ── Chef's Assistant intro (guide image "Fragen ohne Tippen.") ───────────────────────────── */
/* The answer card is the only teal-bordered surface in the app: it is the one place where the
   assistant has already done the work, and the guide gives it that weight. */
.v2-chef-answer{
  background: linear-gradient(160deg, rgba(11,216,182,0.10), rgba(11,216,182,0.02) 60%);
  border: 1px solid var(--copper);
  border-radius: 16px;
  padding: 16px 18px 18px;
  margin: 0 0 14px;
}
.v2-chef-q{
  font-family: var(--font-heading);
  font-size: 19px;
  font-weight: 700;
  line-height: 1.3;
  color: var(--ink);
  margin: 8px 0 12px;
}
.v2-chef-a{
  font-family: var(--font-data);
  font-size: 38px;
  font-weight: 700;
  line-height: 1;
  color: var(--copper);
  margin: 0 0 8px;
  display: flex;
  align-items: baseline;
  gap: 6px;
}
/* A prompt is a <button>, so it needs the row look reset onto it — .v2-row alone inherits the
   UA button background, border and centred text. */
.v2-chef-prompt{
  width: 100%;
  text-align: left;
  font: inherit;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
}
.v2-chef-prompt:hover{ border-color: var(--copper); }
.v2-chef-prompt .v2-row-title{ font-size: 16px; }

/* ── Recipe food-cost card: one wide KPI instead of the 3-up grid ────────────────────────── */
.v2-kpi-wide{
  display: block;
  margin: 0 0 16px;
}
.v2-kpi-wide .v2-kpi-value{ font-size: 42px; }

/* Hosts for the v2 sections that live inside an existing view (Lager, Check List) get the same
   18px gutter as .home-grid — the views around them have no padding of their own. */
#sauteroLagerV2Host:not(:empty){
  display: block;
  padding: 14px 18px 0;
}

/* The stock table is a desktop shape in the style guide (Artikel · Ort · Bestand · Min. ·
   Status). Five columns do not fit 430 px: measured on the phone capture, the "nachbestellen"
   pill was cut off at the right edge — the one cell in the row that tells you to act. The
   location is the column a cook can most afford to lose there, because the article name already
   implies it and the row is tappable through to the ingredient. Only .stock is narrowed; the
   recipe table has three columns and fits as it is. */
@media (max-width: 560px){
  .v2-table.stock th:nth-child(2),
  .v2-table.stock td:nth-child(2){ display: none; }
  .v2-table.stock th,
  .v2-table.stock td{ padding-right: 6px; }
  .v2-table.stock .v2-pill{ padding: 4px 8px; font-size: 11px; }
}

/* ══ ERP desktop, ZADANIE §3A ═══════════════════════════════════════════════════════════════
   Page 04 of the visual manual is a whole screen, and it is the target — "postav to presne
   takto, len v novej palete a písmach". Every number below is measured off that page, not
   estimated: 238 px column, 38 px brand tile, 10 px / 1.3 px group labels, 38 px rows at 9 px
   radius, 17 px icons beside 13.5 px text, 11.5 px / .9 px tabs, 10.5 px card kickers, 33 px
   values. Spacing is the eight-point grid of §2.6.
   ─────────────────────────────────────────────────────────────────────────────────────────── */
:root{
  --erp-topbar-h: 56px;
  --erp-side-w: 238px;
}

/* The wordmark on a surface that is dark in BOTH themes (top bar, sidebar). Without this the
   light theme would paint "Saut" in #21201c onto #0A1A2F — a 1.2 : 1 pair, i.e. invisible. */
.brand-on-dark .brand-logo{ color: #EEEEEC; }
.brand-on-dark .brand-logo > i{ color: #0BD8B6; }

.desktop-erp-topbar{
  display: none;
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: var(--erp-topbar-h);
  z-index: 130;
  box-sizing: border-box;
  align-items: center;
  gap: 16px;
  padding: 0 16px;
  background: var(--brand-dark);
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}
body.desktop-erp-active .desktop-erp-topbar{ display: flex; }
.desktop-erp-topbar-brand{ display: flex; align-items: center; gap: 10px; min-width: var(--erp-side-w); }
.desktop-erp-topbar-mark{
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  flex: none;
  border-radius: 10px;
  background: var(--teal9);
}
.desktop-erp-topbar-word{ display: flex; flex-direction: column; gap: 1px; line-height: 1.15; }
.desktop-erp-topbar-sub{ font-family: var(--font-ui); font-size: 10.5px; color: #8D8D86; }
.desktop-erp-topbar-demo{ flex: none; margin-left: auto; }

/* §3.6 — the demo switch is a badge in this bar, not a floating box, and it says what it is:
   "DEMO DÁTA — nie produkčné". Amber carries black text (§2.5: 13.3 : 1); teal-on-dark would
   read as a normal action, which is the one thing this control must not look like. */
.desktop-erp-demo-badge{
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  border-radius: 9px;
  border: 1px solid var(--amber);
  background: transparent;
  color: var(--amber);
  font-family: var(--font-ui);
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
}
.desktop-erp-demo-badge.is-on{ background: var(--amber); color: var(--on-amber); }

/* Quick picks 1–4 in the top bar (Richard, 2. 9. 2026). Same shell as the Mobile/ERP segmented
   control: a quiet dark cluster, the current screen lit in teal, empty slots dashed. The 📌 opens
   a small chooser that pins the OPEN screen — the bar is on every screen, so the pin is too. */
.desktop-erp-quick{ position: relative; display: flex; align-items: center; gap: 6px; margin-right: 14px; }
.desktop-erp-quick-eyebrow{ font-size: 10.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  color: #8D8D86; margin-right: 4px; }
.desktop-erp-quick-slot{ display: inline-flex; align-items: center; gap: 6px; height: 34px; padding: 0 10px 0 6px;
  border-radius: 9px; border: 1px solid rgba(255,255,255,0.14); background: rgba(255,255,255,0.05);
  color: #EEEEEC; font-family: var(--font-ui); font-size: 12px; font-weight: 600; cursor: pointer; max-width: 150px; }
.desktop-erp-quick-slot .desktop-erp-nav-icon{ width: 16px; height: 16px; flex: none; display: inline-flex; }
.desktop-erp-quick-slot .desktop-erp-nav-icon svg{ width: 16px; height: 16px; }
.desktop-erp-quick-n{ width: 18px; height: 18px; border-radius: 6px; display: inline-flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 800; background: rgba(255,255,255,0.10); color: #C9C9C3; flex: none; }
.desktop-erp-quick-label{ overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.desktop-erp-quick-slot.is-empty{ border-style: dashed; color: #8D8D86; }
.desktop-erp-quick-slot.is-current{ background: rgba(11,216,182,0.16); border-color: rgba(11,216,182,0.45); color: var(--teal11); }
.desktop-erp-quick-slot.is-current .desktop-erp-quick-n{ background: var(--teal9); color: #062A22; }
.desktop-erp-quick-slot:hover{ border-color: rgba(255,255,255,0.32); }
/* ‹ Späť — o jednu obrazovku (Richard, 5. 9. 2026): tvar rýchlej voľby, stojí pred ňou v lište. */
.desktop-erp-back{ display: inline-flex; align-items: center; gap: 5px; height: 34px; padding: 0 12px 0 9px; margin-right: 8px;
  border-radius: 9px; border: 1px solid rgba(255,255,255,0.14); background: rgba(255,255,255,0.05);
  color: #EEEEEC; font-family: var(--font-ui); font-size: 12px; font-weight: 600; cursor: pointer; flex: none; }
.desktop-erp-back-chev{ font-size: 18px; line-height: 1; margin-top: -2px; }
.desktop-erp-back:hover:not(:disabled){ border-color: rgba(255,255,255,0.32); }
.desktop-erp-back:disabled{ opacity: 0.38; cursor: default; }
.desktop-erp-quick-pin{ height: 34px; width: 34px; border-radius: 9px; border: 1px solid rgba(255,255,255,0.14);
  background: rgba(255,255,255,0.05); font-size: 15px; cursor: pointer; line-height: 1; }
.desktop-erp-quick-pin.is-open, .desktop-erp-quick-pin:hover{ border-color: var(--teal9); background: rgba(11,216,182,0.16); }
.desktop-erp-quick-slot:focus-visible, .desktop-erp-quick-pin:focus-visible, .desktop-erp-quick-pop-btn:focus-visible{ outline: 2px solid var(--teal9); outline-offset: 2px; }
.desktop-erp-quick-pop{ position: absolute; top: calc(100% + 10px); right: 0; z-index: 131; min-width: 320px;
  padding: 12px; border-radius: 12px; background: var(--brand-dark); border: 1px solid rgba(255,255,255,0.16);
  box-shadow: 0 12px 32px rgba(0,0,0,0.45); color: #EEEEEC; }
.desktop-erp-quick-pop-title{ font-size: 12px; font-weight: 600; margin-bottom: 10px; color: #C9C9C3; }
.desktop-erp-quick-pop-row{ display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; }
.desktop-erp-quick-pop-btn{ display: flex; flex-direction: column; align-items: center; gap: 3px; padding: 8px 4px; border-radius: 9px;
  border: 1px solid rgba(255,255,255,0.14); background: rgba(255,255,255,0.05); color: #EEEEEC; cursor: pointer; font-family: var(--font-ui); min-width: 0; }
.desktop-erp-quick-pop-btn b{ font-size: 14px; }
.desktop-erp-quick-pop-btn small{ font-size: 10.5px; color: #8D8D86; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.desktop-erp-quick-pop-btn:hover{ border-color: var(--teal9); background: rgba(11,216,182,0.16); }
.desktop-erp-quick-pop-btn.is-current{ border-color: rgba(11,216,182,0.45); }
.desktop-erp-quick-pop-clear{ margin-top: 10px; width: 100%; padding: 6px; border-radius: 8px; border: 1px dashed rgba(255,255,255,0.2);
  background: transparent; color: #8D8D86; font-size: 11.5px; cursor: pointer; }
.desktop-erp-quick-pop-clear:hover{ color: #EEEEEC; }
@media (max-width: 1180px){ .desktop-erp-quick-slot{ max-width: 40px; padding: 0 6px; } .desktop-erp-quick-label, .desktop-erp-quick-eyebrow{ display: none; } }

/* Row typography on the ERP layout (Richard, 2. 9. 2026: recipe rows too big, ingredient rows too
   small — both take the ingredients-list style, 20 % larger). Ingredients list: 15/12.5/14 px →
   18/15/16.8 px. Recipe detail table: the 44 px kitchen tap floor is a phone rule (wet fingers);
   a mouse gets 30 px targets and the row falls from ~72 px to ~44 px. */
body.desktop-erp-active .ingredient-row{ padding: 7px 18px; }
body.desktop-erp-active .ingredient-row .info .name{ font-size: 18px; line-height: 1.3; }
body.desktop-erp-active .ingredient-row .info .meta{ font-size: 15px; line-height: 1.3; }
body.desktop-erp-active .ingredient-row .price{ font-size: 16.8px; }
body.desktop-erp-active .ingredient-row .cuisine-badge{ font-size: 12px; }
/* 3. 9. 2026 (Richard: „ingrediencie v receptoch presne ako v zozname ingrediencií"): the name
   cell carries the SAME four values as `.ingredient-row .info .name` above (18 px / 700 /
   var(--sage) / var(--font-data) / 1.3) and the row takes the same vertical rhythm — 7 px of
   padding like the list row, 26 px targets instead of 30 — so a recipe row is ~38 px tall,
   the height of an ingredient row, not a taller band that reads as a bigger font. */
body.desktop-erp-active table.ing td{ padding: 6px 0; font-family: var(--font-data); font-size: 18px; font-weight: 700; color: var(--sage); line-height: 1.3; }
body.desktop-erp-active table.ing td:first-child{ grid-template-columns: minmax(0, 1fr) 26px 26px; column-gap: 4px; }
body.desktop-erp-active table.ing td.qty{ font-size: 16.8px; font-weight: 400; color: var(--copper); padding-left: 14px; }
/* The phone's 44×44 touch minimum (úloha 24) is what made a recipe row 55 px against the 38 px
   ingredient row — same 18 px name, taller row, and it read as a bigger font (Richard, 3. 9. 2026).
   The ERP layout is mouse-driven: 26 px buttons, and the row lands on the ingredient list's rhythm. */
body.desktop-erp-active table.ing td:first-child > .cost-info-btn{ width: 26px; height: 26px; min-width: 26px; min-height: 26px; font-size: 11px; }
body.desktop-erp-active table.ing .cost-info-btn::before{ inset: 4px; }
.desktop-erp-demo-badge:focus-visible{ outline: 2px solid var(--teal9); outline-offset: 2px; }

/* ── Sidebar to the page-04 measurements ──────────────────────────────────────────────────── */
body.desktop-erp-active{ --desktop-erp-sidebar-w: var(--erp-side-w); }
body.desktop-erp-active #desktopErpShell.desktop-erp-shell{
  top: var(--erp-topbar-h);
  /* §3A gives the column #191918 — the guide's "podklad sekcie", one step off the app
     background, not the background itself. --sand2 is that token and it flips with the theme. */
  background: var(--sand2);
  border-right: 1px solid var(--rule);
}
body.desktop-erp-active #desktopErpMain.desktop-erp-main{ top: var(--erp-topbar-h); }
body.desktop-erp-active .desktop-erp-brand{ padding: 16px 16px 8px; font-size: 19px; }
body.desktop-erp-active .desktop-erp-nav{ padding: 8px 12px 16px; gap: 2px; }
body.desktop-erp-active .desktop-erp-nav-section{
  margin: 16px 0 6px;
  padding: 0 10px;
  font-family: var(--font-ui);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 1.3px;
  color: #6F6E69;
}
body.desktop-erp-active .desktop-erp-nav-item{
  min-height: 38px;
  padding: 0 10px;
  border-radius: 9px;
  font-family: var(--font-ui);
  font-size: 13.5px;
  font-weight: 500;
  color: var(--ink-dim);
}
body.desktop-erp-active .desktop-erp-nav-icon{ font-size: 17px; width: 20px; }
body.desktop-erp-active .desktop-erp-nav-item:hover{ background: rgba(18, 165, 148, 0.08); color: var(--ink); }
/* §3A: "Nikdy plná tyrkysová plocha — biely text na tyrkysovej neprejde kontrast." */
body.desktop-erp-active .desktop-erp-nav-item[aria-current="page"]{
  background: rgba(18, 165, 148, 0.13);
  /* The guide's #0bd8b6 is the DARK-surface brand text; --teal11 is that value in dark and
     #008573 in light, where mint on a near-white column is 1.7 : 1. §2.5. */
  color: var(--teal11);
  box-shadow: inset 2px 0 0 var(--teal9);
}

/* ── Dashboard body ───────────────────────────────────────────────────────────────────────── */
.erp-dash{ display: block; }
.erp-dash-bar{
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 0 16px;
}
.erp-crumb{
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-ui);
  font-size: 13px;
  color: var(--ink-dim);
}
.erp-crumb-here{ color: var(--ink); font-weight: 600; }
.erp-bar-right{ display: flex; align-items: center; gap: 8px; margin-left: auto; }
.erp-icon-btn,
.erp-ghost-btn{
  display: inline-flex;
  align-items: center;
  gap: 7px;
  min-height: 34px;
  padding: 0 12px;
  border-radius: 9px;
  border: 1px solid var(--rule);
  background: var(--paper-raised);
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
}
.erp-icon-btn{ width: 34px; padding: 0; justify-content: center; }
.erp-user-chip{
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 34px;
  padding: 0 12px 0 5px;
  border-radius: 999px;
  border: 1px solid var(--rule);
  background: var(--paper-raised);
  font-family: var(--font-ui);
  font-size: 12.5px;
  color: var(--ink);
}
.erp-user-initials{
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--teal9);
  color: var(--on-teal);
  font-size: 11px;
  font-weight: 700;
}

.erp-tabs{
  display: flex;
  align-items: center;
  gap: 4px;
  border-bottom: 1px solid var(--rule);
  margin: 0 0 16px;
}
.erp-tab{
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 10px 14px;
  border: none;
  border-bottom: 2px solid transparent;
  background: transparent;
  color: var(--ink-dim);
  font-family: var(--font-ui);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.9px;
  text-transform: uppercase;
  cursor: pointer;
}
.erp-tab:hover{ color: var(--ink); }
.erp-tab[aria-selected="true"]{ color: var(--copper); border-bottom-color: var(--teal9); }
.erp-tabs-kitchen{
  margin-left: auto;
  padding-right: 4px;
  font-family: var(--font-ui);
  font-size: 11.5px;
  color: var(--ink-dim);
}

.erp-filters{ display: flex; align-items: center; gap: 8px; margin: 0 0 16px; }
.erp-search{
  flex: 1;
  min-width: 0;
  min-height: 38px;
  padding: 0 12px;
  border-radius: 9px;
  border: 1px solid var(--rule);
  background: var(--paper-raised);
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: 13px;
}
.erp-select{
  min-height: 38px;
  padding: 0 30px 0 12px;
  border-radius: 9px;
  border: 1px solid var(--rule);
  background: var(--paper-raised);
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: 13px;
}
/* §3A: "Na obrazovke je primárne tlačidlo práve jedno." */
.erp-primary-btn{
  min-height: 38px;
  padding: 0 16px;
  border-radius: 9px;
  border: none;
  background: var(--teal9);
  color: var(--on-teal);
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
}

.erp-kpis{
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 16px;
  margin: 0 0 16px;
}
.erp-kpi{
  padding: 16px;
  border-radius: 13px;
  border: 1px solid var(--card-rule);
  background: var(--paper);
}
.erp-kpi-kicker{
  margin: 0 0 10px;
  font-family: var(--font-ui);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.9px;
  text-transform: uppercase;
  color: var(--ink-dim);
}
.erp-kpi-value{
  margin: 0 0 8px;
  font-family: var(--font-ui);
  font-size: 33px;
  font-weight: 600;
  line-height: 1;
  color: var(--ink);
}
.erp-kpi-foot{ margin: 0; font-family: var(--font-ui); font-size: 12px; color: var(--ink-dim); }
/* Direction × whether up is good — never the movement alone (§3A, food cost down is green). */
.erp-kpi-foot.good{ color: var(--ok-green-text); }
.erp-kpi-foot.warn{ color: var(--amber-text); }
.erp-kpi-foot.bad{ color: var(--red-text); }

.erp-panels{
  display: grid;
  grid-template-columns: minmax(0, 1.35fr) minmax(0, 0.85fr) minmax(0, 1fr);
  gap: 16px;
  margin: 0 0 16px;
  align-items: start;
}
.erp-panel{
  padding: 16px;
  border-radius: 13px;
  border: 1px solid var(--card-rule);
  background: var(--paper);
  box-sizing: border-box;
}
.erp-panel-head{ display: flex; align-items: baseline; gap: 12px; margin: 0 0 14px; }
.erp-panel-title{
  font-family: var(--font-heading);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  color: var(--ink);
}
.erp-panel-note{ margin-left: auto; font-family: var(--font-ui); font-size: 12px; color: var(--ink-dim); }
.erp-panel-note.good{ color: var(--ok-green-text); }
.erp-panel-note.warn{ color: var(--amber-text); }
.erp-donut-wrap{ display: flex; flex-direction: column; align-items: center; gap: 12px; }
.erp-legend{ display: flex; flex-wrap: wrap; justify-content: center; gap: 6px 14px; margin: 0; padding: 0; list-style: none; }
.erp-legend li{
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-ui);
  font-size: 11.5px;
  color: var(--ink-dim);
}
.erp-legend-dot{ width: 8px; height: 8px; border-radius: 50%; flex: none; }
.erp-alerts{ display: flex; flex-direction: column; gap: 8px; }
.erp-alert{
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 11px 12px;
  border-radius: 10px;
  border: 1px solid var(--rule);
  background: var(--paper-raised);
}
.erp-alert-icon{ font-size: 14px; flex: none; }
.erp-alert-icon.warn{ color: var(--amber-text); }
.erp-alert-icon.temp{ color: var(--red-text); }
.erp-alert-icon.info{ color: var(--ink-dim); }
.erp-alert-text{ font-family: var(--font-ui); font-size: 12.5px; color: var(--ink); }
.erp-alert-text b{ font-weight: 600; }
.erp-alert-text span{ color: var(--ink-dim); }

.erp-prod{
  padding: 16px;
  border-radius: 13px;
  border: 1px solid var(--card-rule);
  background: var(--paper);
}
.erp-prod-head{ display: flex; align-items: center; gap: 8px; margin: 0 0 12px; }
.erp-prod-head .erp-panel-title{ margin-right: auto; }
.erp-prod table{ width: 100%; border-collapse: collapse; }
.erp-prod th{
  padding: 8px 10px;
  border-bottom: 1px solid var(--rule);
  font-family: var(--font-ui);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.9px;
  text-transform: uppercase;
  color: var(--ink-dim);
  text-align: left;
}
.erp-prod td{
  padding: 12px 10px;
  border-bottom: 1px solid var(--rule);
  font-family: var(--font-ui);
  font-size: 13px;
  color: var(--ink);
}
.erp-prod tr:last-child td{ border-bottom: none; }
.erp-prod .num{ text-align: right; font-variant-numeric: tabular-nums; }
.erp-prod .id{ color: var(--ink-dim); font-variant-numeric: tabular-nums; }
.erp-prod .cost{ font-weight: 600; }

/* Narrower desktops: the three panels stack two-then-one rather than squeezing the donut. */
@media (max-width: 1180px){
  .erp-kpis{ grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .erp-panels{ grid-template-columns: minmax(0, 1fr); }
}

/* "Spalten" on page 04 hides the food-cost column — the one column a kitchen turns off when the
   screen is on the wall and a guest can read it. Header and cell are both column 7. */
.erp-prod table.erp-hide-cost th:nth-child(7),
.erp-prod table.erp-hide-cost td:nth-child(7){ display: none; }

/* ═══════════════════════════════════════════════════════════════════════════════════════
   SURFACE LAYER (Richard, 3. 9. 2026 — docs/SAUTERO_CLAUDE_MOBILE_DESKTOP.md)
   One app, two surfaces. app/js/ui_surface.js sets body.surface-mobile / body.surface-erp
   from the one getSurface(); a block that belongs to one surface carries data-surface and
   the other surface never draws it. No module writes its own breakpoint for this.
   ═══════════════════════════════════════════════════════════════════════════════════════ */
body.surface-mobile [data-surface="erp"]{ display:none !important; }
body.surface-erp [data-surface="mobile"]{ display:none !important; }

/* ── bottom bar — five 44px+ targets, thumb reach, no hover state ── */
.mobile-nav{
  position:fixed; left:0; right:0; bottom:0; z-index:40;
  display:none; align-items:stretch; justify-content:center;
  height:calc(64px + env(safe-area-inset-bottom, 0px));
  padding:0 4px env(safe-area-inset-bottom, 0px);
  background:var(--paper);
  border-top:1px solid var(--rule);
  box-shadow:0 -6px 20px rgba(0,0,0,0.25);
}
.mobile-nav-btn{
  flex:1 1 0; max-width:128px; min-width:44px; min-height:44px;
  background:none; border:none; color:var(--ink-dim);
  display:flex; flex-direction:column; align-items:center; justify-content:center; gap:3px;
  padding:6px 2px; cursor:pointer;
  font-family:var(--font-ui); font-size:11px; font-weight:600; letter-spacing:.02em; line-height:1.1;
  -webkit-tap-highlight-color:transparent;
}
.mobile-nav-btn svg{ width:22px; height:22px; flex:none; }
.mobile-nav-btn.is-active{ color:var(--copper); }
.mobile-nav-btn:active{ transform:scale(0.94); }
.mobile-nav-label{ white-space:nowrap; overflow:hidden; text-overflow:ellipsis; max-width:100%; }
/* The bar takes the bottom strip: the page and every fixed bubble down there move up by its height. */
body.has-mobile-nav{ padding-bottom:calc(104px + 64px + env(safe-area-inset-bottom, 0px)); }
body.has-mobile-nav .global-feedback-btn{ bottom:calc(22px + 64px + env(safe-area-inset-bottom, 0px)); }
body.has-mobile-nav .back-to-top-btn{ bottom:calc(24px + 64px + env(safe-area-inset-bottom, 0px)); }
/* Kolo 29 (Richard, 7. 9. 2026, snímka Stations so zakrúžkovanými kolieskami: „spodná lišta zakrýva
   tlačítka"). Zmerané v Chromiu na 390 px: plávajúce tlačidlo končilo na 820 px, lišta začína na 780
   — teda 40 px pod ňou, palcom nedosiahnuteľných. Susedné plávajúce prvky (späť hore, spätná väzba,
   sken) túto kompenzáciu mali od začiatku, `.fab` sa na ten zoznam nikdy nedostala. */
body.has-mobile-nav .fab{ bottom:calc(24px + 64px + env(safe-area-inset-bottom, 0px)); }
body.has-mobile-nav #globalFeedbackMenu{ bottom:calc(74px + 64px + env(safe-area-inset-bottom, 0px)); }
body.has-mobile-nav #bgScanPill{ bottom:calc(12px + 64px + 64px + env(safe-area-inset-bottom, 0px)); }
/* Chef's Assistant is a full-screen chat with its own input at the bottom. */
body.chef-chat-open .mobile-nav{ display:none !important; }
@media print{ .mobile-nav{ display:none !important; } }

/* ── "now" panel on the phone Home: open items, one tick each, two alarm counts, outbox ── */
.now-panel{
  margin:4px 16px 12px; padding:14px 14px 8px;
  background:var(--paper); border:1px solid var(--rule); border-radius:16px;
}
.now-panel:empty{ display:none; }
.now-head{ display:flex; align-items:center; justify-content:space-between; gap:8px; }
.now-kicker{ margin:0; font-size:11px; letter-spacing:.16em; text-transform:uppercase; color:var(--copper); font-weight:700; }
.now-sync{ font-size:11.5px; font-weight:600; color:var(--ok-green-text); white-space:nowrap; }
.now-sync.is-wait{ color:var(--amber-text); }
.now-strip{ display:grid; grid-template-columns:repeat(3, minmax(0, 1fr)); gap:8px; margin:10px 0 4px; }
.now-stat{
  min-height:56px; border:1px solid var(--rule); border-radius:12px;
  background:var(--paper-raised); color:var(--ink);
  display:flex; flex-direction:column; align-items:flex-start; justify-content:center;
  padding:8px 10px; font-family:var(--font-ui); cursor:pointer; text-align:left;
}
.now-stat b{ font-family:var(--font-data); font-size:22px; font-weight:700; line-height:1; }
.now-stat span{ font-size:11px; color:var(--ink-dim); margin-top:3px; line-height:1.15; }
.now-stat.is-alarm b{ color:var(--red-text); }
.now-list{ display:flex; flex-direction:column; margin-top:4px; }
.now-row{ display:flex; align-items:center; gap:12px; min-height:56px; padding:6px 0; border-top:1px solid var(--rule); }
.now-tick{
  flex:none; width:44px; height:44px; border-radius:50%;
  border:2px solid var(--copper); background:transparent; color:transparent;
  display:flex; align-items:center; justify-content:center; cursor:pointer; padding:0;
  -webkit-tap-highlight-color:transparent;
}
.now-tick:active{ transform:scale(0.92); }
.now-row.is-done .now-tick{ background:var(--copper); color:var(--on-teal); }
.now-row.is-done .now-row-name{ text-decoration:line-through; color:var(--ink-dim); }
.now-row-text{ flex:1; min-width:0; }
.now-row-name{ font-size:16px; font-weight:600; color:var(--ink); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.now-row-meta{ font-size:12px; color:var(--ink-dim); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.now-prio{ flex:none; font-family:var(--font-data); font-size:11px; font-weight:700; padding:3px 7px; border-radius:999px; background:var(--paper-raised); color:var(--ink-dim); }
.now-prio.is-top{ background:var(--amber); color:var(--on-amber); }
.now-more{ width:100%; min-height:44px; margin-top:2px; border:none; background:none; color:var(--copper); font-family:var(--font-ui); font-size:14px; font-weight:700; cursor:pointer; }
.now-empty{ margin:10px 0 0; color:var(--ink-dim); font-size:14px; }
/* Office preview of the phone surface (Mobil toggle on a wide screen): keep the panel phone-wide,
   same 640px the .home-grid already uses, instead of stretching one tick across 1280px. */
@media (min-width: 560px){ .now-panel{ max-width:640px; margin-left:auto; margin-right:auto; } }

/* ══════════════════════════════════════════════════════════════════════════════════════════
   CHECK LIST — DESKTOP v2 (Richard, 4. 9. 2026, docs/SAUTERO_CLAUDE_CHECKLIST_DESKTOP.md)
   Náčrt A–E: docs/sketch/2026-09-04_cl-desktop-sketch.html. Farby v náčrte boli VYZNAČENIE
   BLOKOV, nie farby appky — tu platí Sautero dark + #12A594, presne ako inde.
   Všetko je trieda, nič nie je style="…": inline_style_guard je ráčňa a šírka stĺpca sa
   nastavuje na uzle (clApplyBarWidths), lebo nameraná hodnota je správanie, nie vzhľad.
   ══════════════════════════════════════════════════════════════════════════════════════════ */

/* ── mriežka obrazovky A ─────────────────────────────────────────────────────────────────── */
.cl-top-grid{ padding-bottom: 0; }
/* DLAŽDICE HUBU V DIZAJNE VIGNIET (Richard, 4. 9. 2026 večer, snímka Missing time: „chcem, aby
   dizajn tých projektov v dlaždici Check List vyzeral ako tieto sekcie — všetky obrazovky
   v Check Liste v rovnakom dizajne"). Len CSS, len ERP povrch: markup dlaždíc (data-tile,
   clTopBook, cl-tile-wide) ostáva, telefón ostáva pri štvorcových ikonách. Ikona + názov na
   jednom riadku, podriadok pod názvom, farebná ľavá hrana ako pri sekcii. */
body.desktop-erp-active #checkListTopTileGrid,
body.desktop-erp-active #checkListBookGrid{
  grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)) !important;
  gap: 10px;
}
body.desktop-erp-active #checkListTopTileGrid .home-tile,
body.desktop-erp-active #checkListBookGrid .home-tile{
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  column-gap: 8px; row-gap: 3px;
  align-items: center; text-align: left;
  min-height: 72px;
  padding: 12px 14px;
  border: 1px solid var(--rule, #3B3A37); border-left: 4px solid var(--rule, #3B3A37);
  border-radius: 12px;
  background: var(--surface, var(--paper-raised, #191918));
}
body.desktop-erp-active #checkListTopTileGrid .home-tile:hover,
body.desktop-erp-active #checkListBookGrid .home-tile:hover{ border-color: var(--teal9, #12A594); }
body.desktop-erp-active #checkListTopTileGrid .home-tile-icon,
body.desktop-erp-active #checkListBookGrid .home-tile-icon{
  width: auto; height: auto; font-size: 17px; background: transparent; border-radius: 0;
}
body.desktop-erp-active #checkListTopTileGrid .home-tile > span:not(.home-tile-icon):not(.cl-tile-sub),
body.desktop-erp-active #checkListBookGrid .home-tile > span:not(.home-tile-icon):not(.cl-tile-sub){
  font-size: 14px; font-weight: 700; overflow-wrap: anywhere;
}
body.desktop-erp-active #checkListTopTileGrid .home-tile > .cl-tile-sub{
  grid-column: 2; font-size: 12px; font-weight: 400; color: var(--ink-dim, #B5B3AD);
}
/* Široká To do vigneta: hlava vľavo, čísla vpravo — ako doteraz, len v rovnakom ráme. */
body.desktop-erp-active #checkListTopTileGrid .home-tile.cl-tile-wide{
  display: flex; justify-content: space-between; align-items: center;
  border-left-color: #12A594;
}
body.desktop-erp-active #checkListTopTileGrid .cl-tile-wide .home-tile-icon{ font-size: 26px; }
/* „nech sú pekne vysvietené" — na desktope žiadna stlmená karta; poznámka „neskôr" ostáva. */
body.desktop-erp-active #checkListTopTileGrid .cl-tile-later{ opacity: 1; }
.cl-back-sections{ display: inline-block; margin: 6px 0 10px; font-size: 13px; font-weight: 700; }
body.desktop-erp-active #checkListTopTileGrid .cl-tile-wide .cl-wide-label{ font-size: 15px; }
/* Farba hrany = identita karty, tá istá paleta ako sekcie (V2_CHART_COLORS). Knihy si držia
   svoje (.cl-book-*). */
/* 5. 9. 2026 v noci: farba hrany ide z JEDNEJ mapy (CL_TILE_COLORS → trieda cl-edge-*), nie z data-tile —
   po výmene mien kníh (9B) ostala kniha jedál bez hrany. Špecifickosť musí prebiť rám dlaždice vyššie. */
body.desktop-erp-active #checkListTopTileGrid .home-tile.cl-edge-teal{ border-left-color: #12A594; }
body.desktop-erp-active #checkListTopTileGrid .home-tile.cl-edge-indigo{ border-left-color: #3E63DD; }
body.desktop-erp-active #checkListTopTileGrid .home-tile.cl-edge-pink{ border-left-color: #D6409F; }
body.desktop-erp-active #checkListTopTileGrid .home-tile.cl-edge-cyan{ border-left-color: #00A2C7; }
body.desktop-erp-active #checkListTopTileGrid .home-tile.cl-edge-plum{ border-left-color: #AB4ABA; }
body.desktop-erp-active #checkListTopTileGrid .home-tile.cl-edge-orange{ border-left-color: #FF9E7A; }
body.desktop-erp-active #checkListTopTileGrid .home-tile.cl-edge-violet{ border-left-color: #B39DFF; }
body.desktop-erp-active #checkListTopTileGrid .home-tile.cl-edge-mint{ border-left-color: #0BD8B6; }
body.desktop-erp-active #checkListTopTileGrid .home-tile.cl-edge-gold{ border-left-color: #FFD166; }
body.desktop-erp-active #checkListTopTileGrid .home-tile.cl-edge-muted{ border-left-color: #B5B3AD; }
body.desktop-erp-active #checkListTopTileGrid [data-tile="addproject-top"],
body.desktop-erp-active #checkListBookGrid [data-tile="addstation"],
body.desktop-erp-active #checkListBookGrid [data-tile="addevent"]{ border-left-color: #B5B3AD; border-style: dashed; }
.cl-tile-later{ opacity: .55; }
.cl-tile-later:hover{ opacity: .85; }

/* ── pravý panel (3 kritické + graf) ─────────────────────────────────────────────────────── */
.cl-rail{ display: flex; flex-direction: column; gap: 14px; }
.cl-rail-card{
  border: 1px solid var(--rule, #3B3A37);
  border-radius: 12px;
  padding: 12px 12px 14px;
  background: var(--surface, var(--paper-raised, #191918));
}
.cl-rail-title{
  margin: 0 0 8px; font-size: 11px; font-weight: 700; letter-spacing: .10em;
  text-transform: uppercase; color: var(--teal9, #12A594);
}
.cl-rail-empty{ margin: 0; font-size: 12px; color: var(--ink-dim, #B5B3AD); }
.cl-rail-list{ list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.cl-rail-item{ display: flex; align-items: flex-start; gap: 8px; }
.cl-rail-dot{ width: 10px; height: 10px; border-radius: 3px; flex: 0 0 auto; margin-top: 3px; }
.cl-rail-body{ display: flex; flex-direction: column; min-width: 0; }
.cl-rail-body b{ font-size: 13px; font-weight: 700; line-height: 1.25; overflow-wrap: anywhere; }
.cl-rail-sub{ font-size: 11px; color: var(--ink-dim, #B5B3AD); overflow-wrap: anywhere; }
/* Chef's assistant analýzy (bod 9, 5. 9. 2026): dokument nad asistentom v identite Sautero. */
.ca-doc{ position: fixed; inset: 0; z-index: 1200; background: var(--bg); color: var(--ink); overflow: auto; display: none; }
body.desktop-erp-active .ca-doc{ left: var(--desktop-erp-sidebar-w, 238px); }
.ca-toolbar{ position: sticky; top: 0; z-index: 2; display: flex; gap: 8px; align-items: center; padding: 10px 16px; background: var(--bg); border-bottom: 1px solid var(--rule); }
.ca-toolbar .ca-close{ margin-left: auto; }
.ca-paper{ max-width: 920px; margin: 0 auto; padding: 22px 24px 60px; }
.ca-kicker{ font-size: 11px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--copper); margin: 0 0 4px; }
.ca-h1{ font-family: Georgia, serif; font-size: 28px; margin: 0 0 4px; color: var(--ink); }
.ca-sub{ color: var(--ink-dim); font-size: 13px; margin: 0 0 10px; }
.ca-demo{ color: var(--gold, #FFC53D); font-size: 12.5px; margin: 0 0 8px; }
.ca-section{ margin: 26px 0 0; padding-top: 14px; border-top: 1px solid var(--rule); page-break-inside: avoid; }
.ca-h2{ font-family: Georgia, serif; font-size: 20px; margin: 0 0 12px; color: var(--copper); }
.ca-kpis{ display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; margin-bottom: 14px; }
.ca-kpi{ border: 1px solid var(--rule); border-left: 4px solid var(--copper); border-radius: 12px; padding: 12px 14px; background: var(--paper); }
.ca-kpi-warn{ border-left-color: var(--danger, #E5484D); }
.ca-kpi-good{ border-left-color: var(--copper); }
.ca-kpi-value{ font-family: var(--font-data); font-size: 26px; font-weight: 700; line-height: 1.1; overflow-wrap: anywhere; }
.ca-kpi-sentence{ font-size: 13px; color: var(--ink-dim); margin-top: 4px; }
.ca-chart{ margin: 6px 0 10px; }
.ca-chart svg{ width: 100%; height: auto; max-width: 560px; }
.ca-table{ width: 100%; border-collapse: collapse; font-size: 13px; margin: 8px 0 12px; }
.ca-table th{ text-align: left; font-size: 11px; text-transform: uppercase; letter-spacing: .06em; color: var(--ink-dim); padding: 6px 8px; border-bottom: 1px solid var(--rule); }
.ca-table td{ padding: 6px 8px; border-bottom: 1px solid var(--rule); }
.ca-table td.ca-num{ font-family: var(--font-data); text-align: right; white-space: nowrap; }
.ca-note{ font-size: 12px; color: var(--ink-dim); margin: 4px 0 8px; }
.ca-empty{ font-size: 13.5px; color: var(--ink-dim); margin: 6px 0; }
.ca-sales-row{ display: flex; flex-wrap: wrap; gap: 10px; align-items: flex-end; margin: 8px 0; }
.ca-sales-row .ca-note{ flex-basis: 100%; }
.ca-sales{ display: flex; flex-direction: column; gap: 4px; font-size: 12px; color: var(--ink-dim); }
.ca-sales input{ width: 130px; padding: 6px 8px; border: 1px solid var(--rule); border-radius: 8px; background: var(--paper); color: var(--ink); font-family: var(--font-data); }
.ca-menu-grid{ display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; margin-top: 14px; }
.ca-menu-btn{ display: flex; align-items: center; gap: 12px; padding: 16px; border: 1px solid var(--rule); border-radius: 14px; background: var(--paper); color: var(--ink); font: inherit; font-size: 15px; text-align: left; cursor: pointer; }
.ca-menu-btn:hover{ border-color: var(--copper); }
.ca-menu-btn[data-kind="all"]{ grid-column: 1 / -1; border-color: var(--copper); }
.ca-menu-icon{ font-size: 22px; }
/* Vignety dodávateľov pod poličkami Surovín (bod 6, 5. 9. 2026) — len ERP; telefón ich nekreslí. */
.supplier-ads{ margin: 18px 0 8px; }   /* ERP okraje nižšie pri .home-grid */
.supplier-ads:empty{ display: none; }
.supplier-ads-title{ font-size: 10.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-dim); margin: 0 0 8px; }
.supplier-ads-row{ display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }
.supplier-ad{ border: 1px solid var(--rule); border-radius: 12px; padding: 12px 14px; background: var(--paper); min-width: 0; }
.supplier-ad.is-collapsed{ display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 6px 12px; opacity: .7; }
.supplier-ad-eyebrow{ font-size: 10.5px; text-transform: uppercase; letter-spacing: .08em; color: var(--ink-dim); margin: 0; }
.supplier-ad-title{ font-family: Georgia, serif; font-size: 16px; color: var(--ink); margin: 4px 0 2px; overflow-wrap: anywhere; }
.supplier-ad-price{ font-family: var(--font-data); font-size: 13px; color: var(--copper); margin: 0; }
.supplier-ad-actions{ display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.supplier-ad-link{ background: none; border: 0; color: var(--copper); font: inherit; font-size: 12px; cursor: pointer; padding: 0; }
.supplier-ads-notice{ display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap;
  border: 1px solid var(--copper); border-radius: 12px; padding: 8px 12px; margin-bottom: 10px; font-size: 13px; }
/* Expirácie → Chef's assistant (bod 8, 5. 9. 2026): jediná akcia v pravom paneli, celá šírka karty. */
.cl-rail-card .cl-rail-cta{ display: block; width: 100%; margin-top: 10px; text-align: center; }
.cl-rail-bars{ display: flex; flex-direction: column; gap: 7px; }
.cl-rail-bar-row{ display: grid; grid-template-columns: minmax(0, 1fr) 84px 46px; gap: 8px; align-items: center; }
.cl-rail-bar-name{ font-size: 12px; overflow-wrap: anywhere; }
.cl-rail-bar-track{ height: 10px; border-radius: 5px; background: var(--rule, #3B3A37); overflow: hidden; display: block; }
.cl-rail-bar-fill{ display: block; height: 100%; border-radius: 5px; width: 2%; }
.cl-rail-bar-val{ font-size: 12px; font-weight: 700; text-align: right; color: var(--ink-dim, #B5B3AD); }
.cl-rail-foot{ margin: 0; font-size: 11px; color: var(--ink-dim, #B5B3AD); }

/* Farby sekcií — tie isté päť sérií, aké drží V2_CHART_COLORS (heute.js). Šiesta je „muted",
   nie vymyslený šiesty odtieň (ZADANIE §3.1: „Deviata farba neexistuje"). */
.cl-sw-teal,   .cl-bg-teal{   background: #12A594; }
.cl-sw-indigo, .cl-bg-indigo{ background: #3E63DD; }
.cl-sw-pink,   .cl-bg-pink{   background: #D6409F; }
.cl-sw-cyan,   .cl-bg-cyan{   background: #00A2C7; }
.cl-sw-plum,   .cl-bg-plum{   background: #AB4ABA; }
.cl-sw-muted,  .cl-bg-muted{  background: #B5B3AD; }

/* ── kalendár obrazovky B (sticky) ───────────────────────────────────────────────────────── */
.cl-calendar-sticky{
  /* Lepí sa POD hornú lištu obrazovky: jej výšku meria clStickyOffset() a píše ako premennú. */
  position: sticky; top: var(--cl-sticky-top, 0px); z-index: 3;
  background: var(--paper, #111110);
  padding-bottom: 8px; margin-bottom: 10px;
}
/* Sticky grafová vigneta obrazoviek B a C (Richard, 4. 9. 2026 večer): stĺpce po dňoch
   + dva koláče (najvyťaženejšia sekcia podľa času / podľa zaškrtnutých) vedľa seba. */
.cl-todo-sticky{
  display: grid; grid-template-columns: minmax(0, 2fr) minmax(180px, 1fr) minmax(180px, 1fr);
  gap: 10px; align-items: start;
}
.cl-todo-sticky .v2-chart-card{ margin: 0; }
.cl-sticky-pie{
  border: 1px solid var(--rule, #3B3A37); border-radius: 12px; padding: 10px 12px;
  background: var(--surface, var(--paper-raised, #191918));
}
.cl-sticky-pie svg{ max-width: 140px; height: auto; display: block; margin: 0 auto; }
.cl-sticky-pie .v2-legend{ font-size: 11px; }
.cl-sticky-pie .cl-vignette-sub{ white-space: normal; overflow-wrap: anywhere; }
/* Riadky vo vignete (dnes objednané po jedlách): názov a počet vedľa seba, nie mriežka lišty. */
.cl-vignette-side .prep-item-row{ display: flex; justify-content: space-between; align-items: center; gap: 8px; padding: 6px 10px; }
.cl-vignette-side .prep-item-row .prep-item-name{ flex: 1 1 auto; font-size: 14px; overflow-wrap: normal; word-break: normal; }
@media (max-width: 1280px){
  .cl-todo-sticky{ grid-template-columns: minmax(0, 1fr) minmax(160px, 1fr); }
  .cl-todo-sticky .cl-sticky-bars{ grid-column: 1 / -1; }
}
/* Progress sekcie (zaškrtnuté z celku) na vignete obrazovky B. */
.cl-progress{ display: block; height: 6px; border-radius: 3px; background: var(--rule, #3B3A37); overflow: hidden; margin-top: 4px; }
.cl-progress-fill{ display: block; height: 100%; border-radius: 3px; width: 0; }
/* Široká vigneta cez celý riadok (3 kritické jedlá + graf jedál) a rozbaľovací panel. */
.cl-vignette-wide{ grid-column: 1 / -1; }
.cl-panel{ margin-top: 10px; border-top: 1px solid var(--rule, #3B3A37); padding-top: 8px; }
.cl-panel .cl-section-heading{ padding-left: 8px; }
.cl-two-bars{ width: 100%; height: auto; display: block; }

/* ── farebné vignety sekcií (B, Missing time) ────────────────────────────────────────────── */
.cl-section-grid{
  display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 10px; margin: 10px 0 4px;
}
.cl-section-vignette{
  display: flex; flex-direction: column; gap: 4px; text-align: left;
  border: 1px solid var(--rule, #3B3A37); border-left-width: 4px; border-radius: 12px;
  padding: 12px 14px; background: var(--surface, var(--paper-raised, #191918));
  color: inherit; cursor: pointer; font: inherit;
}
.cl-section-vignette:hover{ border-color: var(--teal9, #12A594); }
.cl-section-head{ display: flex; align-items: center; gap: 8px; }
.cl-section-icon{ font-size: 17px; }
.cl-section-name{ font-size: 14px; font-weight: 700; overflow-wrap: anywhere; }
.cl-section-line{ font-size: 12px; color: var(--ink-dim, #B5B3AD); overflow-wrap: anywhere; }
.cl-section-heading{
  margin: 14px 0 6px; font-size: 13px; font-weight: 700; letter-spacing: .02em;
}

/* ── štyri vignety obrazovky C ───────────────────────────────────────────────────────────── */
.cl-vignette-grid{
  display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 12px;
}
.cl-vignette, .cl-hero, .cl-haccp-block, .cl-order-block{
  border: 1px solid var(--rule, #3B3A37); border-radius: 12px; padding: 14px;
  background: var(--surface, var(--paper-raised, #191918)); margin-bottom: 12px;
}
.cl-vignette-title{ margin: 0 0 10px; font-size: 13px; font-weight: 700; }
.cl-vignette-sub{ margin: 0 0 6px; font-size: 12px; color: var(--ink-dim, #B5B3AD); }
.cl-vignette-body{ display: flex; flex-wrap: wrap; gap: 14px; align-items: flex-start; }
.cl-vignette-side{ flex: 1 1 180px; min-width: 0; }
.cl-top3{ margin: 0; padding-left: 18px; font-size: 12px; }
.cl-top3 li{ margin-bottom: 4px; overflow-wrap: anywhere; }
.cl-top3 li span{ color: var(--ink-dim, #B5B3AD); margin-left: 6px; }
.cl-wide-action{ display: block; width: 100%; margin-top: 8px; }

/* ── Inventory ───────────────────────────────────────────────────────────────────────────── */
/* Zarovnanie (Richard, 5. 9. 2026 v noci, bod 8, so snímkou: polia množstva v rôznej výške podľa jednotky):
   pravý stĺpec má PEVNÚ šírku, pole aj jednotka pevnú šírku, extra riadok má rovnakú ľavú hranu
   (transparentnú) ako ostatné — text začína všade v tom istom bode. */
.cl-inv-right{ display: flex; align-items: center; justify-content: flex-end; gap: 8px; flex: 0 0 auto; }
.cl-inv-row{ border-left: 4px solid transparent; }
.cl-inv-row .cl-inv-right{ width: 176px; }
.cl-inv-qty{ width: 92px; flex: 0 0 92px; text-align: right; box-sizing: border-box; }
.cl-inv-unit{ width: 72px; flex: 0 0 72px; box-sizing: border-box; padding: 4px 6px; }
.cl-inv-extra{ border-left: 4px solid #AB4ABA; }
.cl-inv-search{ width: 240px; max-width: 100%; }
.cl-inv-search-btn.active{ border-color: var(--teal9, #12A594); }
/* Order: koláč po sekciách + zoznam podľa dodávateľa (bod 4). Značka sekcie = malý štvorček vpravo. */
.cl-order-pie-toggle{ display: flex; justify-content: space-between; align-items: center; width: 100%;
  background: none; border: 0; color: inherit; font: inherit; padding: 0; cursor: pointer; text-align: left; }
.cl-order-pie-toggle .cl-vignette-title{ margin: 0; }
.cl-order-pie .cl-vignette-body{ margin-top: 10px; }
.cl-order-supplier-list{ margin-top: 10px; border-top: 1px solid var(--rule, #3B3A37); }
.cl-order-sup-row .cl-inv-right{ width: 176px; }
.cl-sec-marks{ display: inline-flex; gap: 4px; min-width: 32px; justify-content: flex-end; }
.cl-sec-mark{ display: inline-block; width: 12px; height: 12px; border-radius: 3px; }
/* Fotka hotovej úlohy v info hárku (bod 3). */
.cl-item-photo{ display: block; width: 100%; max-height: 320px; object-fit: cover; border-radius: 10px; margin: 6px 0 8px; }
.cl-item-photo-block{ margin: 6px 0 10px; }
.cl-item-photo-actions{ margin-top: 6px; }
body.desktop-erp-active .prep-line-one .prep-info-btn{ min-width: 30px; font-weight: 700; font-family: Georgia, serif; }
body.desktop-erp-active .prep-line-one .prep-info-btn.active{ border-color: var(--teal9, #12A594); color: var(--teal9, #12A594); }
/* Zaškrtávací zoznam: políčko vľavo od názvu, spočítaný riadok ho má vyplnené (Richard,
   4. 9. 2026 večer: „zaškrtávací zoznam všetkých firemných ingrediencií"). */
.cl-tick{
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; margin-right: 8px; border-radius: 4px; flex: 0 0 auto;
  border: 1.5px solid var(--rule, #3B3A37); font-size: 12px; font-weight: 700; color: #F4EFE6;
  vertical-align: middle;
}
.cl-inv-counted .cl-tick{ background: var(--teal9, #12A594); border-color: var(--teal9, #12A594); }
.cl-inv-counted .prep-item-name{ opacity: .75; }
.cl-inv-bar{ display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.cl-inv-tally{ margin-left: auto; font-size: 12px; }

/* ── HACCP checklist ─────────────────────────────────────────────────────────────────────── */
.cl-haccp-done .prep-item-name{ opacity: .6; text-decoration: line-through; }

/* ── Plates / Order riadky ───────────────────────────────────────────────────────────────── */
/* Vypredané je prepínač na riadku jedla (nie odznak): zapnutý = červený, lebo to je STATUS
   (ZADANIE §3.5 — červená patrí stavu, nie ozdobe). */
.cl-soldout-btn.active{ background: #E5484D; border-color: #E5484D; color: #fff; }
.plates-comp-recipe{ border-left: 3px solid var(--teal9, #12A594); }
.plates-comp-open{ text-align: left; }
.plates-comp-unroll{ min-width: 28px; padding-left: 6px; padding-right: 6px; }
.plates-comp-head{ display: flex; align-items: center; gap: 6px; min-width: 0; }
/* Rozbalený vnorený recept: odsadený pod svojím riadkom, tá istá tealová hrana. */
.plates-nested{ margin-left: 18px; border-left: 2px solid var(--rule, #3B3A37); padding-left: 8px; }
.cl-order-recipe > .prep-dish-header{ border-left: 3px solid var(--teal9, #12A594); }

/* Mobil (getSurface() = 'mobile'): ten istý obsah pod sebou, nie druhý renderer. */
@media (max-width: 1023px){
  .cl-section-grid{ grid-template-columns: 1fr; }
  .cl-vignette-grid{ grid-template-columns: 1fr; }
  .cl-calendar-sticky{ position: static; }
}

/* Pravý panel na obrazovkách, ktoré vyhradený stĺpec v markupe nemajú (#tasksView). Vyrába ho
   clRailHost() — rovnaký vzor, aký používa desktop_shell.js; ráčňa monolitu nedovolí pridať
   ďalší markup do app/index.html, a obchádzať ju kvôli dvom riadkom by bolo presne to, čo
   CLAUDE.md zakazuje. */
/* DVA POKUSY, DVA NÁLEZY ZO SNÍMKY (4. 9. 2026):
   1. `position:absolute; top:0` — sticky lišta (z-index 10) prekryla hornú kartu panelu.
   2. `display:grid` na #tasksView — obrazovku otvára `style.display='block'` priamo na uzle
      a inline štýl mriežku prebije. Grid, ktorý zapne CSS a vypne JS, nie je layout.
   Zostáva absolútny stĺpec NAD lištou (z-index 11) a hlavný obsah, ktorý mu vedľa seba nechá
   miesto. Triedu `cl-has-rail` vešia clRailHost(), takže obrazovka BEZ panelu odsadenie nemá. */
body.desktop-erp-active #tasksView.cl-has-rail{ position: relative; }
body.desktop-erp-active #tasksView.cl-has-rail > .cl-rail-aside{
  /* STĹPEC V OBRAZOVKE, NIE VO VIEWPORTE. `position: fixed; right: 20px` meral od okraja okna,
     obsah od okraja obrazovky — na Richardovej 2000 px obrazovke sa panel prekryl s vignetou
     Inventory o 24 px (5. 9. 2026). Absolútny stĺpec vpravo v #tasksView cez celú jeho výšku
     a v ňom STICKY slot: panel ostáva na obrazovke pri skrolovaní (Richard, 4. 9.: „dve pod
     sebou sticky vignety") a obsah mu vedľa seba nechá presne toľko miesta, koľko má. */
  position: absolute; top: 0; right: 20px; bottom: 0;
  width: 280px; z-index: 11;
  margin: 0;   /* .desktop-erp-hub-aside má margin-right 20 px — tu by posunul panel o 20 px do obsahu */
}
body.desktop-erp-active #tasksView.cl-has-rail > .cl-rail-aside > .cl-rail-slot{
  position: sticky; top: 12px;
  max-height: calc(100vh - var(--erp-topbar-h, 56px) - 24px); overflow: auto;
}
/* Hub: vyhradený stĺpec shellu je grid položka — sticky drží, kým je hlavný stĺpec vyšší. */
body.desktop-erp-active #checkListProjectsView .desktop-erp-hub-aside[data-hub-aside]{
  position: sticky; top: calc(var(--erp-topbar-h, 56px) + 12px); align-self: start;
}
body.desktop-erp-active #tasksView.cl-has-rail > .sticky-header,
body.desktop-erp-active #tasksView.cl-has-rail > #taskListContainer,
body.desktop-erp-active #tasksView.cl-has-rail > #checkListTiles{
  padding-right: 316px;   /* 20 px okraj + 280 px panel + 16 px medzera — presne, nie približne */
}
/* Missing time (Richard, 5. 9. 2026): sekcie v jednom stĺpci vľavo, graf sticky pod hlavičkou
   presne medzi stĺpcom sekcií a pravým panelom. */
body.desktop-erp-active .cl-missing-layout{
  display: grid; grid-template-columns: 300px minmax(0, 1fr); gap: 14px; align-items: start;
}
body.desktop-erp-active .cl-missing-sections .cl-section-grid{ grid-template-columns: 1fr; margin: 0; }
body.desktop-erp-active .cl-missing-chart{ position: sticky; top: var(--cl-sticky-top, 0px); margin: 0; }
@media (max-width: 1023px){
  #tasksView.cl-has-rail > .cl-rail-aside{ position: static; width: auto; padding: 0; }
  #tasksView.cl-has-rail > .sticky-header,
  #tasksView.cl-has-rail > #taskListContainer,
  #tasksView.cl-has-rail > #checkListTiles{ padding-right: 0; }
}

/* Neutrálny riadok. `.prep-item-row` má jantárový podklad, lebo v Check Liste znamená
   „je na zozname" — v Inventory a v HACCP by tá istá farba čítala ako výstraha na každom
   riadku. Jantár, červená a zelená sú STATUS farby (ZADANIE §3.5) a na bežnom riadku
   nemajú čo robiť. */
.prep-item-row.cl-plain-row{ background: transparent; }

/* Farebná hrana sekcie stojí AŽ TU, za `.cl-vignette / .cl-hero / .cl-haccp-block`, ktoré
   nastavujú `border` skratkou. Skratka prepíše aj border-left-color — takže keď boli tieto
   pravidlá vyššie, hrany boli sivé a farba sekcie sa na obrazovku nedostala vôbec (videné na
   snímke, 4. 9. 2026: sivé okraje na vignetách aj na HACCP blokoch). */
.cl-edge-teal{   border-left: 4px solid #12A594; }
.cl-edge-indigo{ border-left: 4px solid #3E63DD; }
.cl-edge-pink{   border-left: 4px solid #D6409F; }
.cl-edge-cyan{   border-left: 4px solid #00A2C7; }
.cl-edge-plum{   border-left: 4px solid #AB4ABA; }
.cl-edge-muted{  border-left: 4px solid #B5B3AD; }
/* Farby kníh (identita dlaždice, 5. 9. 2026) — tie isté hexy ako .cl-book-* nižšie v súbore. */
.cl-edge-orange{ border-left: 4px solid #FF9E7A; }
.cl-edge-violet{ border-left: 4px solid #B39DFF; }
.cl-edge-mint{   border-left: 4px solid #0BD8B6; }
.cl-edge-gold{   border-left: 4px solid #FFD166; }
.cl-sw-orange, .cl-bg-orange{ background: #FF9E7A; }
.cl-sw-violet, .cl-bg-violet{ background: #B39DFF; }
.cl-sw-mint,   .cl-bg-mint{   background: #0BD8B6; }
.cl-sw-gold,   .cl-bg-gold{   background: #FFD166; }
/* Dlaždice hubu v dizajne vignety sekcie (Richard, 5. 9. 2026 so snímkami). */
body.desktop-erp-active #checkListTopTileGrid .home-tile.cl-hub-tile,
body.desktop-erp-active #checkListProjectsGrid .home-tile.cl-hub-tile{
  display: flex; flex-direction: column; align-items: flex-start; justify-content: flex-start; gap: 4px;
  min-height: 92px; padding: 12px 14px; text-align: left;
}
body.desktop-erp-active #checkListTopTileGrid .home-tile.cl-hub-tile .cl-section-line,
body.desktop-erp-active #checkListProjectsGrid .home-tile.cl-hub-tile .cl-section-line{ font-size: 12px; font-weight: 400; color: var(--ink-dim, #B5B3AD); }
body.desktop-erp-active #checkListTopTileGrid .home-tile.cl-hub-tile .cl-section-name{ font-size: 14px; font-weight: 700; }
body.desktop-erp-active #checkListTopTileGrid .home-tile.cl-tile-wide.cl-hub-tile{ flex-direction: row; align-items: center; justify-content: space-between; min-height: 72px; }
body.desktop-erp-active #checkListTopTileGrid .cl-tile-wide .cl-wide-left{ display: flex; flex-direction: column; gap: 4px; }
/* Tón hlavičky projektu vo farbe dlaždice — jemný prechod zľava + 2 px linka, nie plná plocha. */
body.desktop-erp-active #tasksView[data-cl-color] .sticky-header{ border-bottom-width: 2px; }
body.desktop-erp-active #tasksView[data-cl-color="teal"] .sticky-header{ border-bottom-color: #12A594; background-image: linear-gradient(90deg, rgba(18,165,148,.14), rgba(18,165,148,0) 60%); }
body.desktop-erp-active #tasksView[data-cl-color="indigo"] .sticky-header{ border-bottom-color: #3E63DD; background-image: linear-gradient(90deg, rgba(62,99,221,.16), rgba(62,99,221,0) 60%); }
body.desktop-erp-active #tasksView[data-cl-color="pink"] .sticky-header{ border-bottom-color: #D6409F; background-image: linear-gradient(90deg, rgba(214,64,159,.14), rgba(214,64,159,0) 60%); }
body.desktop-erp-active #tasksView[data-cl-color="cyan"] .sticky-header{ border-bottom-color: #00A2C7; background-image: linear-gradient(90deg, rgba(0,162,199,.16), rgba(0,162,199,0) 60%); }
body.desktop-erp-active #tasksView[data-cl-color="plum"] .sticky-header{ border-bottom-color: #AB4ABA; background-image: linear-gradient(90deg, rgba(171,74,186,.14), rgba(171,74,186,0) 60%); }
body.desktop-erp-active #tasksView[data-cl-color="orange"] .sticky-header{ border-bottom-color: #FF9E7A; background-image: linear-gradient(90deg, rgba(255,158,122,.16), rgba(255,158,122,0) 60%); }
body.desktop-erp-active #tasksView[data-cl-color="violet"] .sticky-header{ border-bottom-color: #B39DFF; background-image: linear-gradient(90deg, rgba(179,157,255,.16), rgba(179,157,255,0) 60%); }
body.desktop-erp-active #tasksView[data-cl-color="mint"] .sticky-header{ border-bottom-color: #0BD8B6; background-image: linear-gradient(90deg, rgba(11,216,182,.14), rgba(11,216,182,0) 60%); }
body.desktop-erp-active #tasksView[data-cl-color="gold"] .sticky-header{ border-bottom-color: #FFD166; background-image: linear-gradient(90deg, rgba(255,209,102,.14), rgba(255,209,102,0) 60%); }
body.desktop-erp-active #tasksView[data-cl-color="muted"] .sticky-header{ border-bottom-color: #B5B3AD; background-image: linear-gradient(90deg, rgba(181,179,173,.12), rgba(181,179,173,0) 60%); }
.cl-inv-extra{   border-left: 4px solid #AB4ABA; }

/* Náčrt D: „Riadok jedla = výška ako riadok ingrediencie." Na desktope má riadok suroviny
   `padding: 6px 10px` (pravidlo body.desktop-erp-active .prep-item-row vyššie); hlavička jedla
   mala 14/18 px a na obrazovke bola takmer dvojnásobná. Rovnaká výška je celý zmysel: kuchár
   číta jeden zoznam, nie dva odlišné. Platí IBA na ERP povrchu — telefón si svoju veľkú
   hlavičku ponecháva, tam sa do nej trafí prst. */
body.desktop-erp-active #tasksView .prep-dish-header{
  padding: 6px 10px;
  align-items: center;
}
body.desktop-erp-active #tasksView .prep-dish-name{ font-size: 18px; line-height: 1.3; }
/* ⋮ jedla (Premenovať / Skryť / Zmazať) — na desktope niet dlhého stisku myšou (Richard, 5. 9. 2026). */
body.desktop-erp-active #tasksView .cl-dish-menu{ min-width: 34px; padding: 4px 8px; }
.plates-comp-add{ margin-left: 6px; }
/* Service time (Richard, 5. 9. 2026): jedlá sekcie ako karty Plates — rovnaký font a veľkosť,
   riadok o tretinu nižší (karta 52 → ~35 px; meria cl_desktop_render_test G_service). */
/* PREDVOLENÉ pre celý Check List na ERP (Richard, 5. 9. 2026 v noci: „font a veľkosť riadku upraviť
   presne ako je teraz v service time a urobiť tento font a veľkosť riadku ako predvolený … vo všetkých
   ostatných obrazovkách check listu"): Plates, Stations, strom Order, HACCP, Inventory, Missing time.
   Selektor .cl-service-compact ostáva (strážca check_cl_service_dish_cards), platí to isté. */
body.desktop-erp-active #tasksView .prep-dish-card,
body.desktop-erp-active #tasksView .cl-service-compact .prep-dish-card{ padding: 2px 0 5px 0; }
body.desktop-erp-active #tasksView .prep-dish-header,
body.desktop-erp-active #tasksView .cl-service-compact .prep-dish-header{ padding: 1px 10px; }
/* Zmerané 5. 9. 2026 (mock, 1440 px): karta Plates 73 px = hlavička 56 (tlačidlá 44) + 16 + 1.
   Tlačidlá a políčko porcií 38 px → hlavička 40, karta 48 px = −34 %. Názov 18 px ostáva. */
body.desktop-erp-active #tasksView .prep-dish-header .task-status-btn,
body.desktop-erp-active #tasksView .prep-dish-header .prep-onhand,
body.desktop-erp-active #tasksView .cl-service-compact .prep-dish-header .task-status-btn,
body.desktop-erp-active #tasksView .cl-service-compact .prep-dish-header .prep-onhand{
  min-height: 38px; height: 38px; box-sizing: border-box; padding: 2px 8px; font-size: 12px; line-height: 1.2; }
body.desktop-erp-active #tasksView .prep-item-row,
body.desktop-erp-active #tasksView .cl-service-compact .prep-item-row{ padding: 2px 10px; }
body.desktop-erp-active #tasksView .prep-line-one .task-status-btn,
body.desktop-erp-active #tasksView .prep-line-one .prep-priority,
body.desktop-erp-active #tasksView .cl-service-compact .prep-line-one .task-status-btn,
body.desktop-erp-active #tasksView .cl-service-compact .prep-line-one .prep-priority{ min-height: 24px; height: auto; padding: 2px 8px; }
body.desktop-erp-active #tasksView .prep-line-one .prep-dots,
body.desktop-erp-active #tasksView .cl-service-compact .prep-line-one .prep-dots{ min-height: 24px; padding: 2px 8px; }
/* Kolo 10C (Richard, 5. 9. 2026 ráno, so snímkou sekcie Stations: „chcem mať takýto font a veľkosť
   riadku všade — buď dôkladný"): KAŽDÝ riadok zoznamu v Check Liste na ERP = riadok Stations —
   názov 18 px / 700 / var(--font-data), riadok ~30 px. Dovtedy 44 px podlaha (kitchen-a11y-floor)
   ostávala v tlačidlách MIMO .prep-line-one (Order · Missing time · HACCP: 49 px), v poliach
   Inventory (49 px), v starom .task-row projektu (104 px) a názov vo vignete To do stál na 14 px.
   Meria cl_desktop_render_test K_rows na desiatich obrazovkách. Telefón: bez zmeny (body.desktop-erp-active). */
body.desktop-erp-active #tasksView .prep-item-row .task-status-btn,
body.desktop-erp-active #tasksView .task-row .task-status-btn{
  min-height: 24px; height: auto; min-width: 0; padding: 2px 8px; font-size: 12.5px; line-height: normal; }
body.desktop-erp-active #tasksView .prep-item-row .prep-input:not(.prep-priority){
  min-height: 24px; height: auto; padding: 2px 6px; font-size: 14px; line-height: normal; }
body.desktop-erp-active #tasksView .prep-item-row .link-btn{ min-height: 24px; padding: 0 6px; line-height: 1.3; }   /* ↗ vnorený recept na Order */
body.desktop-erp-active #tasksView .prep-item-row .plates-comp-open .meta{ font-size: 13px; font-weight: 400; }
/* Riadky vo vignete (dnes objednané po jedlách): pri 18 px sa názov vedľa koláča orezal na „Rin…" —
   stĺpec s riadkami ide pod koláč na celú šírku vignety (koláč hore, zoznam pod ním). */
body.desktop-erp-active #tasksView .cl-vignette-side:has(.prep-item-row){ flex-basis: 260px; }
body.desktop-erp-active #tasksView .cl-inv-right{ gap: 6px; }
body.desktop-erp-active #tasksView .cl-vignette-side .prep-item-row{ padding: 2px 10px; }
body.desktop-erp-active #tasksView .cl-vignette-side .prep-item-row .prep-item-name{
  font-size: 18px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Stará mriežka úloh (.task-row: vlastné projekty) v tom istom kabáte: názov | stavy vpravo. */
body.desktop-erp-active #tasksView .task-row{
  display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; column-gap: 16px;
  padding: 2px 10px; font-family: var(--font-data); }
body.desktop-erp-active #tasksView .task-row-top{ align-items: center; min-width: 0; }
body.desktop-erp-active #tasksView .task-row .task-text{ font-size: 18px; font-weight: 700; line-height: 1.3; color: var(--sage); }
body.desktop-erp-active #tasksView .task-row .task-status-group{ margin-top: 0; gap: 6px; }
body.desktop-erp-active #tasksView .task-row .task-note,
body.desktop-erp-active #tasksView .task-row .meta{ font-size: 13px; margin-top: 0; }
/* Zoznamy top 3 / top 6 vo vignetách hlavného stĺpca: názov v tom istom písme (12 px → 18 px / 700). */
body.desktop-erp-active #taskListContainer .cl-top3{ font-size: 18px; font-family: var(--font-data); }
body.desktop-erp-active #taskListContainer .cl-top3 li{ margin-bottom: 2px; line-height: 1.3; }
body.desktop-erp-active #taskListContainer .cl-top3 li span{ font-size: 13px; }
/* bod 7: mriežka vlastných projektov pod „Aktuálne čísla" — knihy majú dlaždice hore, tu sú skryté. */
body.desktop-erp-active #checkListProjectsGrid .cl-projects-heading{ grid-column: 1 / -1; margin: 12px 0 0; }
body.desktop-erp-active #checkListProjectsGrid .home-tile.cl-project-book{ display: none; }
#checkListProjectsGrid .cl-projects-heading{ display: none; }
body.desktop-erp-active #checkListProjectsGrid .cl-projects-heading{ display: block; }

/* Kolo 11A (Richard, 5. 9. 2026 ráno, body 1–3): riadok = názov (30 znakov + …) · značka · ⋮; ponuky pri
   riadku (značka, ⋮ bez hárku); hárok ⋮ so všetkým, čo z riadku odišlo; ⋮ projektu a dlaždice. */
.cl-nm{ display: inline-block; max-width: 30ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: bottom; }
body.desktop-erp-active #tasksView .prep-item-name,
body.desktop-erp-active #tasksView .prep-dish-name{ white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
body.desktop-erp-active #tasksView .prep-line-one,
body.desktop-erp-active #tasksView .cl-inv-right,
body.desktop-erp-active #tasksView .prep-dish-header-right{ position: relative; }
.cl-mark-pop, .cl-row-menu{
  position: absolute; right: 0; top: calc(100% + 4px); z-index: 6; display: flex; gap: 4px; padding: 6px;
  background: var(--surface, var(--paper-raised, #191918)); border: 1px solid var(--rule, #3B3A37); border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0,0,0,.35); white-space: nowrap; }
.cl-row-menu[hidden]{ display: none; }
.cl-mark{ min-width: 34px; font-size: 13px; }
.cl-mark-off{ opacity: .55; }
.cl-mark-done{ color: var(--teal11, #0BD8B6); border-color: var(--teal9, #12A594); }
.cl-mark-no{ border-color: #E5484D; }
.cl-mark-warn{ border-color: var(--sage, #FFC53D); }
.cl-mark-opt{ font-size: 15px; }
.cl-sheet-actions{ margin: 0 0 8px; }
.cl-sheet-actions .task-status-group{ flex-wrap: wrap; margin-top: 8px; }
.cl-sheet-marks .cl-mark-opt{ min-width: 48px; }
.cl-sheet-prio{ display: inline-flex; align-items: center; gap: 6px; }
.cl-sheet-prio .prep-priority{ width: 64px; }
.cl-project-actions{ display: flex; justify-content: flex-end; margin: 10px 0 4px; }
.cl-tile-dots{ position: absolute; top: 8px; right: 10px; padding: 2px 8px; border-radius: 6px; border: 1px solid var(--rule, #3B3A37);
  color: var(--ink-dim, #B5B3AD); font-weight: 700; line-height: 1.2; cursor: pointer; }
.cl-tile-dots:hover{ color: var(--ink, #EEEEEC); border-color: var(--ink-dim, #B5B3AD); }
body.desktop-erp-active #tasksView .prep-dish-header .prep-dish-total-time{ font-size: 12px; }
body.desktop-erp-active #checkListProjectsGrid .home-tile{ position: relative; }

/* Kolo 11B (Richard, 5. 9. 2026 ráno, bod 3): značky v To do, blok Štart pod koláčmi (vypĺňa prázdne
   miesto sticky lišty), obrazovka Štart (riadok = názov · značka), panel s progresom a HACCP. */
.cl-todo-sticky .cl-sticky-bars{ grid-row: 1 / 3; }
.cl-sticky-start{
  grid-column: 2 / 4; grid-row: 2; border: 1px solid var(--rule, #3B3A37); border-radius: 12px; padding: 10px 12px;
  background: var(--surface, var(--paper-raised, #191918)); }
.cl-sticky-start .cl-start-btn{ width: 100%; margin: 0 0 8px; }
.cl-sticky-start .cl-start-meta{ margin: 6px 0 0; }
.cl-start-secs{ flex-wrap: wrap; margin-top: 0; }
.cl-start-secs .cl-start-sec{ min-height: 30px; }
.cl-marks{ font-size: 12px; font-weight: 400; color: var(--ink-dim, #B5B3AD); margin-left: 8px; white-space: nowrap; }
.cl-start-row .cl-mark{ min-width: 44px; }
.cl-start-done .prep-item-name{ opacity: .55; text-decoration: line-through; }
.cl-start-hero .cl-progress{ margin-top: 8px; }
.cl-start-pct{ font-size: 28px; font-weight: 800; margin: 0 0 6px; line-height: 1.1; }
.cl-start-haccp summary{ cursor: pointer; font-weight: 700; font-size: 13px; }
.cl-start-haccp .cl-rail-item{ display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.cl-start-haccp .task-status-btn{ min-height: 26px; min-width: 0; padding: 2px 8px; font-size: 12px; }
@media (max-width: 1280px){
  .cl-todo-sticky .cl-sticky-bars{ grid-row: auto; }
  .cl-sticky-start{ grid-column: 1 / -1; grid-row: auto; }
}

/* Kolo 11C (Richard, 5. 9. 2026 ráno, body 4–5): Missing time po jedlách, Inventory po kategóriách + koláč
   kategórií + A–Z zoznam s číslom. */
/* Kolo 20: tri koláče v hero Inventory (spočítané / kategórie / sekcie) v TEJ ISTEJ výške — menšie SVG, riadková legenda. */
.cl-inv-pies{ display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; align-items: start; }
.cl-inv-pies .cl-vignette-body svg{ max-width: 118px; height: auto; }
.cl-pie-legend.cl-pie-inline{ flex-direction: row; flex-wrap: wrap; align-items: center; gap: 2px 6px; margin: 6px 0 0; }
.cl-pie-legend.cl-pie-inline .cl-pie-link, .cl-pie-legend.cl-pie-inline .cl-pie-row{ width: auto; min-height: 22px; padding: 1px 6px; font-size: 11px; }
.cl-pie-legend.cl-pie-inline .cl-pie-lbl{ max-width: 11ch; }
.cl-pie-legend .cl-pie-link.active{ background: rgba(52,247,215,.14); color: var(--ink); box-shadow: inset 0 0 0 1px var(--teal9, #12A594); }
.cl-inv-filter-clear{ white-space: nowrap; }
.cl-rail-bar-link{ cursor: pointer; border-radius: 6px; }
.cl-rail-bar-link:hover, .cl-rail-bar-link:focus-visible{ background: rgba(255,255,255,.06); outline: none; }
.cl-inv-cat-body[hidden]{ display: none; }
.cl-inv-num{ display: inline-block; min-width: 2.4em; color: var(--ink-dim, #B5B3AD); font-weight: 400; }
body.desktop-erp-active #tasksView .cl-inv-cat .prep-dish-header .prep-dish-total-time{ font-size: 12px; }
@media (max-width: 1280px){ .cl-inv-pies{ grid-template-columns: minmax(0, 1fr); } }
/* [hidden] MUSÍ vyhrať nad každým display (nález render testu 11C, 5. 9. 2026): pravidlo prehliadača
   [hidden]{display:none} má nižšiu prioritu než KAŽDÉ autorské pravidlo, takže
   body.desktop-erp-active .prep-item-row{display:grid} kreslilo „skrytý" riadok Inventory ďalej — lupa
   z 10B na desktope neskryla ani jeden riadok a test to nevidel, lebo meral vlastnosť .hidden, nie layout.
   Jedno globálne pravidlo pre celú triedu chýb namiesto opravy po triede (.cl-row-menu[hidden] z 11A
   bol prvý taký prípad). Strážca: check_hidden_attr_wins. */
[hidden]{ display: none !important; }

/* ── Kolo 12 (mobil, Richard 5. 9. 2026 17:03): kompaktná horná lišta Home. Namerané pred zmenou 221 px
   (kicker + ikony na dva riadky, Sautero, riadok Settings). Po zmene ~110 px: riadok 1 = ⚙️ · Sautero
   (v strede, absolútne — strany nemusia byť rovnako široké) · 🔔, riadok 2 = Firma/Osobné · 🎭 Demo.
   Všetky ciele ostávajú 44 px (kitchen-a11y-floor). Uzly presúva ui_surface.js (mobileCompactHomeTopbar),
   index.html sa nemení. Demo (prepínač aj pás) je na Home V lište; fixný rám ostáva pre ostatné obrazovky. */
body.surface-mobile #homeView .topbar.mtb-compact{ padding: 8px 12px 8px; }
/* Demo ZAPNUTÉ: pás v lište, na celú šírku, nad riadkom ⚙️ · Sautero · 🔔 (fixný rám je na Home vypnutý). */
body.surface-mobile .mtb-compact .mtb-demo-banner:empty{ display: none; }
/* ─── Kolo 26 (Richard 7. 9. 2026, dve snímky): „chcem aby aj na telefóne boli vignety stations
   v rovnakom style vignety projektov farebne rozlíšené.“ Sekcie kreslí ten istý staviteľ ako na ERP
   (clSectionVignettesHtml), takže farba sekcie príde z triedy `cl-edge-*` sama; tu sa dolaďuje len
   HUSTOTA na tvar widgetu z hubu — 2 stĺpce, 16 px rohy, ikona v 36 px štvorci, meno na jeden riadok
   s výpustkou. Zámerne zrkadlí blok `#checkListProjectsView .home-tile.cl-hub-tile` nižšie: to sú tie
   „vignety projektov“, na ktoré Richard ukázal. */
body.surface-mobile:not(.desktop-erp-active) #tasksView .cl-project-sections .cl-section-grid{
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
  /* Kolo 28: bočný okraj 18 px — TEN ISTÝ, aký má mriežka dlaždíc (`.home-grid`, padding 10px 18px).
     Do 28 tu stálo `margin: 10px 0 4px` a vignety sedeli natvrdo na oboch hranách displeja; zmerané
     na živom builde 5a13843 (390 px): dlaždice 0–190 a 200–390, teda hrana druhej presne na okraji
     výrezu. Nebolo to orezanie (scrollWidth 390 = šírka), ale ani „v rovnakom style vignety
     projektov", na ktoré Richard ukázal — tie 18 px odsadenie majú. */
  margin: 10px 18px 4px;
}
body.surface-mobile:not(.desktop-erp-active) #tasksView .cl-project-sections .cl-section-vignette{
  min-height: 104px;
  align-items: flex-start;
  justify-content: flex-start;
  gap: 0;
  padding: 12px;
  border-radius: 16px;
  min-width: 0;
}
body.surface-mobile:not(.desktop-erp-active) #tasksView .cl-project-sections .cl-section-head{
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
  width: 100%;
  min-width: 0;
}
body.surface-mobile:not(.desktop-erp-active) #tasksView .cl-project-sections .cl-section-icon{
  width: 36px;
  height: 36px;
  font-size: 20px;
  line-height: 1;
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: 10px;
}
body.surface-mobile:not(.desktop-erp-active) #tasksView .cl-project-sections .cl-section-name{
  display: block;
  max-width: 100%;
  min-width: 0;
  font-size: 14.5px;
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.25;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  overflow-wrap: normal;
  hyphens: none;
}
body.surface-mobile:not(.desktop-erp-active) #tasksView .cl-project-sections .cl-section-line{
  display: block;
  max-width: 100%;
  margin-top: 3px;
  font-size: 12px;
  font-weight: 500;
  line-height: 1.25;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  overflow-wrap: normal;
}
/* „+ Add section“ stojí pod vignetami vo vlastnej mriežke — nech je to ten istý widget,
   nie štvorcová dlaždica Home (rovnako ako „Add Project“ na hube). */
body.surface-mobile:not(.desktop-erp-active) #tasksView #checkListBookGrid{
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}
body.surface-mobile:not(.desktop-erp-active) #tasksView #checkListBookGrid .home-tile{
  aspect-ratio: auto;
  min-height: 104px;
  align-items: flex-start;
  justify-content: flex-start;
  gap: 8px;
  padding: 12px;
  border-radius: 16px;
  text-align: left;
}

/* ─── Kolo 25 (Richard 7. 9. 2026, snímka „sushi station“): „Urob to tak aby to bolo v jednom riadku
   a riadok Sprav aby bol čo najmenší a obrazovku sa zmestilo čo najviac surovín.“

   ZMERANÉ PRED (390×844): riadok 90 px, meno hore a značky pod ním (dva riadky), 6 surovín na obrazovku.
   Meno a značky teraz stoja VEDĽA SEBA a riadok stlačí padding na 2 px. Čo ho drží na ~49 px, je
   kuchynská podlaha 44 px pre mokrý palec (jej blok stojí vyššie v tomto súbore) — tú NEZNIŽUJEM,
   lebo cieľ na telefóne je jediné miesto, kde tá podlaha naozaj chráni kuchára. Meno tej značky sem
   NEPÍŠEM: `kitchen_a11y --selftest` ju maže ako JEDINÝ výskyt, aby overil, že strážca jej stratu
   uvidí — druhá zmienka v próze ten podvrh umlčí (rodina zápisu 350). Šírka tlačidiel podlahu nedrží už
   od 31. 7. (`.prep-line-one .task-status-btn{min-width:0}`), takže sa značky do jedného riadku zmestia.

   Platí LEN pre zoznam surovín pod jedlom (`.prep-item-table`) — teda aj pre obrazovku Štart, ktorá
   ten istý obal používa. Inventory a HACCP riadky majú vlastné vstupy a tie sa tu nechytajú. */
body.surface-mobile:not(.desktop-erp-active) #tasksView .prep-item-table .prep-item-row{
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 2px 6px;
}
body.surface-mobile:not(.desktop-erp-active) #tasksView .prep-item-table .prep-item-row .prep-line1{
  flex: 1 1 auto;
  min-width: 0;
  margin-bottom: 0;
  flex-wrap: nowrap;
  gap: 6px;
}
body.surface-mobile:not(.desktop-erp-active) #tasksView .prep-item-table .prep-item-row .prep-item-name{
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  overflow-wrap: normal;
}
body.surface-mobile:not(.desktop-erp-active) #tasksView .prep-item-table .prep-item-row .prep-line-one{
  flex: none;
  overflow: visible;
  padding-bottom: 0;
  gap: 3px;
}
body.surface-mobile .mtb-compact .mtb-demo-banner .sautero-global-demo-banner{ margin: -8px -12px 6px; }
body.surface-mobile .mtb-compact > .u-r-dflexaicenter{ position: relative; min-height: 44px; justify-content: space-between; gap: 6px; }
body.surface-mobile .mtb-compact .kicker{ display: none; }
body.surface-mobile .mtb-compact .mtb-settings{
  position: relative; flex: none; width: 44px; min-width: 44px; height: 44px; padding: 0;
  justify-content: center; border-radius: 12px; font-size: 20px; line-height: 1;
}
body.surface-mobile .mtb-compact .mtb-settings > span,
body.surface-mobile .mtb-compact .mtb-settings > svg{ display: none; }
body.surface-mobile .mtb-compact h1.brand-mark{
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  margin: 0; font-size: 26px; line-height: 1; white-space: nowrap; pointer-events: none;
}
body.surface-mobile .mtb-compact .u-r-dflexaicenter2{ flex: none; flex-wrap: nowrap; min-width: 44px; justify-content: flex-end; }
body.surface-mobile .mtb-compact .mode-toggle-zone{ display: flex; justify-content: center; align-items: center; gap: 8px; margin-top: 6px; flex-wrap: wrap; }
body.surface-mobile .mtb-compact .u-m6-prelatdflex{ display: none; }
body.surface-mobile .mtb-compact .mtb-demo-slot:empty{ display: none; }
body.surface-mobile .mtb-compact .mtb-demo-slot .sautero-global-demo-toggle{ min-height: 44px; border-radius: 999px; padding: 6px 14px; font-size: 12.5px; }
body.surface-mobile .mtb-compact #settingsDropdown{ margin-top: 0; }
/* Plávajúca lišta ostatných obrazoviek: rovnaká značka bez podtitulu (len Sautero). */
body.surface-mobile .floating-nav .fn-kicker{ display: none; }

/* ── Kolo 13 (mobil, Richard 5. 9. 2026 21:05, snímka hubu Check Listu): „daj text len do jedného riadku vo
   vignetách a nech to vyzerá ako by to robili v Apple". Namerané: 3 stĺpce × 103 px, hlava vignety
   (ikona · tučné meno v jednom riadku, dedené z ERP) → meno sa láme uprostred slova („Stat/ions",
   „Ser/vice tim/e", po nemecky „Sta/tio/nen"). Apple vzor = widget: 2 stĺpce, ikona v tónovanom
   štvorci hore vľavo, pod ňou nadpis v JEDNOM riadku (výpustka, nikdy zlom slova), pod ním jeden
   riadok podtitulu; ostrá typografia, ticho, žiadne ozdoby. Farebná hrana dlaždice (identita z 9C)
   ostáva. ERP bez zmeny — preto `:not(.desktop-erp-active)`: render test ERP (cl_desktop_render_test) si
   ERP triedu vnucuje na strom, ktorý sám vyhodnotil ako mobil, a bez tejto poistky sa dlaždice kníh na hube
   ERP odkryli (brána 5. 9. 2026 večer, A_home bookHidden). */
body.surface-mobile:not(.desktop-erp-active) #checkListProjectsView .home-grid.cl-top-grid,
body.surface-mobile:not(.desktop-erp-active) #checkListProjectsView #checkListProjectsGrid{
  /* !important: #checkListTopTileGrid má vyššie tvrdé repeat(3) !important (3 stĺpce boli zámer
     na šírke telefónu; 2 stĺpce sú teraz to, čo drží nadpis v jednom riadku v každom jazyku). */
  grid-template-columns: repeat(2, minmax(0, 1fr)) !important; gap: 10px;
}
/* Široká dlaždica To do: hlava (ikona · meno) a riadok s číslami POD sebou — v rade sa riadok lámal
   po znakoch (na 360 px 180 px vysoký). Ikona 62 px a spodné odsadenie ostávajú, ako boli odsúhlasené. */
body.surface-mobile:not(.desktop-erp-active) #checkListProjectsView .home-tile.cl-tile-wide .cl-wide-left{
  flex-direction: column; align-items: flex-start; gap: 6px; min-width: 0; flex: 1 1 auto;
}
body.surface-mobile:not(.desktop-erp-active) #checkListProjectsView .home-tile.cl-tile-wide .cl-wide-left .cl-section-line{
  display: block; max-width: 100%; font-size: 12px; font-weight: 500; line-height: 1.25;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; overflow-wrap: normal;
}
body.surface-mobile:not(.desktop-erp-active) #checkListProjectsView .home-tile.cl-tile-wide .cl-wide-right{ flex: none; }
/* Jedna veľkosť ikony VŠADE (Richard: „ikona je niekde väčšia a niekde menšia — nech je to jednotné"):
   aj široká To do má štvorec 36 px s 20 px glyfom ako ostatné widgety; tým pádom aj rovnaká výška
   dlaždice (spodné odsadenie 46 px zo 4./5. 8. patrilo k 62 px ikone). */
body.surface-mobile:not(.desktop-erp-active) #checkListProjectsView .home-tile.cl-tile-wide{
  padding: 12px 14px 12px 12px; min-height: 107px; align-items: center; border-radius: 16px;
}
body.surface-mobile:not(.desktop-erp-active) #checkListProjectsView .home-tile.cl-tile-wide .cl-section-head{ display: flex; flex-direction: column; align-items: flex-start; gap: 8px; min-width: 0; }
body.surface-mobile:not(.desktop-erp-active) #checkListProjectsView .home-tile.cl-tile-wide .cl-section-icon{
  width: 36px; height: 36px; font-size: 20px; line-height: 1; flex: none;
  display: flex; align-items: center; justify-content: center;
  background: var(--paper); border: 1px solid var(--rule); border-radius: 10px;
}
body.surface-mobile:not(.desktop-erp-active) #checkListProjectsView .home-tile.cl-tile-wide .cl-wide-left{ gap: 0; }
body.surface-mobile:not(.desktop-erp-active) #checkListProjectsView .home-tile.cl-tile-wide .cl-wide-left .cl-section-line{ margin-top: 3px; }
body.surface-mobile:not(.desktop-erp-active) #checkListProjectsView .home-tile.cl-hub-tile:not(.cl-tile-wide){
  aspect-ratio: auto; min-height: 104px;
  display: flex; flex-direction: column; align-items: flex-start; justify-content: flex-start; gap: 0;
  padding: 12px 12px 12px 12px; border-radius: 16px; text-align: left; min-width: 0;
}
body.surface-mobile:not(.desktop-erp-active) #checkListProjectsView .home-tile.cl-hub-tile:not(.cl-tile-wide) .cl-section-head{
  display: flex; flex-direction: column; align-items: flex-start; gap: 8px; width: 100%; min-width: 0;
}
body.surface-mobile:not(.desktop-erp-active) #checkListProjectsView .home-tile.cl-hub-tile:not(.cl-tile-wide) .cl-section-icon{
  width: 36px; height: 36px; font-size: 20px; line-height: 1; flex: none;
  display: flex; align-items: center; justify-content: center;
  background: var(--paper); border: 1px solid var(--rule); border-radius: 10px;
}
body.surface-mobile:not(.desktop-erp-active) #checkListProjectsView .home-tile.cl-hub-tile .cl-section-name,
body.surface-mobile:not(.desktop-erp-active) #checkListProjectsView .home-tile.cl-hub-tile .cl-wide-label{
  display: block; max-width: 100%; min-width: 0;
  font-size: 14.5px; font-weight: 600; letter-spacing: -0.01em; line-height: 1.25;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; overflow-wrap: normal; hyphens: none;
}
body.surface-mobile:not(.desktop-erp-active) #checkListProjectsView .home-tile.cl-hub-tile:not(.cl-tile-wide) .cl-section-line{
  display: block; max-width: 100%; margin-top: 3px;
  font-size: 12px; font-weight: 500; line-height: 1.25; color: var(--ink-dim, #B5B3AD);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; overflow-wrap: normal;
}
/* Add Project: rovnaký widget (＋ v štvorci, jeden riadok), nie štvorcová dlaždica Home. */
body.surface-mobile:not(.desktop-erp-active) #checkListProjectsView .cl-top-grid .home-tile[data-tile="addproject-top"]{
  aspect-ratio: auto; min-height: 104px; align-items: flex-start; justify-content: flex-start; gap: 8px;
  padding: 12px; border-radius: 16px; text-align: left;
}
body.surface-mobile:not(.desktop-erp-active) #checkListProjectsView .cl-top-grid .home-tile[data-tile="addproject-top"] .home-tile-icon{
  width: 36px; height: 36px; font-size: 20px; line-height: 1; border-radius: 10px;
}
body.surface-mobile:not(.desktop-erp-active) #checkListProjectsView .cl-top-grid .home-tile[data-tile="addproject-top"] .home-tile-label{
  text-align: left; font-size: 14.5px; font-weight: 600; letter-spacing: -0.01em; line-height: 1.25;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; overflow-wrap: normal; hyphens: none;
}
/* Richard 5. 9. 2026 večer: „niektoré žiaria menej a niektoré viac — nech žiaria rovnako intenzívne" →
   dlaždice „neskôr" už nie sú stlmené; o hĺbke hovorí podtitul „neskôr", nie priesvitnosť. */
body.surface-mobile:not(.desktop-erp-active) #checkListProjectsView .cl-top-grid .cl-tile-later{ opacity: 1; }

/* ── Kolo 14 (Richard 6. 9. 2026, snímka Stations · starters/cold, ERP): (1) výstraha „aj v inom jedle" nesmie
   zvýšiť riadok — riadok ostáva 30 px, odlíši sa farbou (jantárový tón + hrana), odznak je 22 px pilulka
   „⚠️ +N" (podlaha 44 px z kitchen-a11y-floor-text tu neplatí, myš nie je mokrý palec — rovnaká výnimka ako
   tlačidlá riadku v 10C); (2) značky ✕ ✅ ❌ ⚠️ ✓ priamo v riadku, aktívna svieti, ostatné stlmené. ── */
body.desktop-erp-active #tasksView .prep-item-row.cl-dup{ background: rgba(255, 197, 61, .10); box-shadow: inset 3px 0 0 #FFC53D; }
body.desktop-erp-active #tasksView .prep-line1 .prep-duplicate-badge.cl-dup-badge{
  min-height: 0; height: 22px; line-height: 20px; padding: 0 8px; font-size: 11px; margin-left: 8px; vertical-align: middle;
}
body.desktop-erp-active #tasksView .cl-marks-inline{ display: inline-flex; align-items: center; gap: 3px; margin-right: 4px; }
body.desktop-erp-active #tasksView .cl-marks-inline .cl-mark-opt{
  min-width: 26px; width: 26px; height: 24px; min-height: 24px; padding: 0; font-size: 13px; line-height: 1; opacity: .42;
}
body.desktop-erp-active #tasksView .cl-marks-inline .cl-mark-opt:hover{ opacity: .85; }
body.desktop-erp-active #tasksView .cl-marks-inline .cl-mark-opt.active{ opacity: 1; background: var(--paper-raised); box-shadow: inset 0 0 0 1px currentColor; }

/* Panel Check Listu má vo vyhradenom stĺpci vlastný uzol PRED Kitchen Figures — hore stojí to,
   čo pomenúva náčrt (3 kritické + graf sekcií), pod tým ostáva, čo tam bolo. */
.cl-rail-slot:not(:empty){ margin-bottom: 14px; }
/* Obrazovka projektu na desktope: vignety sekcií hore, dlaždica „+ Add section" pod nimi. */
body.desktop-erp-active #tasksView .cl-project-sections{ margin: 6px 0 4px; }
body.desktop-erp-active #tasksView .cl-project-sections + .home-grid{ padding-top: 4px; }
/* Tie isté karty aj v hlavnom stĺpci pod dlaždicami (KPI slot shellu, snímka Richarda 4. 9. večer). */
.desktop-erp-hub-kpi[data-cl-owned] .cl-hub-main .cl-rail-card{ background: var(--paper, #111110); }

/* Druhý stĺpec riadku panelu (náčrt C: čas + počet). Sedí tesne pod prvým, aby sa čítali ako
   jedna dvojica, nie ako dva nezávislé riadky. */
.cl-rail-bar-second{ margin-top: -4px; }
.cl-rail-bar-second .cl-rail-bar-track{ height: 6px; }

/* Kolo 15 (Richard 6. 9. 2026, snímka To do list): výseč, riadok legendy aj nadpis koláča sú cesty (klik otvorí
   sekciu / HACCP). Kolo 19: koláč úloh po sekciách a HACCP KPI stoja v PRAVOM PANELI To do (.cl-rail-pies), lišta má
   späť stĺpce + dva koláče + Štart — štyri koláče v lište zabrali na 2000 px celý výrez a sekcie zmizli pod ním. */
.cl-todo-sticky .cl-sticky-pie{ align-self: stretch; }
/* Karta stĺpcov drží výšku svojich riadkov (koláče sú s legendou vyššie): tabuľka ide na spodok, nie diera pod kartou. */
.cl-todo-sticky .cl-sticky-bars{ align-self: stretch; }
.cl-todo-sticky .cl-sticky-bars > .v2-chart-card{ height: 100%; box-sizing: border-box; display: flex; flex-direction: column; }
.cl-todo-sticky .cl-sticky-bars > .v2-chart-card > details{ margin-top: auto; }
.cl-rail .cl-rail-pies .cl-sticky-pie{ margin: 0 0 10px; }
.cl-rail .cl-rail-pies .cl-sticky-pie svg{ max-width: 110px; }
.cl-pie-legend{ flex-direction: column; align-items: stretch; gap: 2px; margin: 8px 0 2px; }
.cl-pie-legend .cl-pie-link, .cl-pie-legend .cl-pie-row{
  display: flex; align-items: center; gap: 6px; width: 100%; min-height: 24px; padding: 2px 6px; border-radius: 6px;
  font-size: 11.5px; font-weight: 600; color: var(--ink-dim); text-align: left; text-decoration: none; }
.cl-pie-legend .cl-pie-link:hover, .cl-pie-legend .cl-pie-link:focus-visible{ background: rgba(255,255,255,.06); color: var(--ink); }
.cl-pie-legend .cl-pie-lbl{ flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cl-pie-legend .cl-pie-n{ flex: 0 0 auto; font-weight: 700; color: var(--ink); }
.cl-pie-legend .cl-pie-link{ background: transparent; border: 0; box-shadow: none; cursor: pointer; }
.cl-pie-all{ display: block; width: 100%; margin: 0 0 4px; padding: 0; background: transparent; border: 0; box-shadow: none;
  text-align: left; text-decoration: none; cursor: pointer; }
.cl-pie-all:hover, .cl-pie-all:focus-visible{ color: var(--teal11, #0BD8B6); }
.v2-slice-link{ cursor: pointer; }
.v2-slice-link:hover{ opacity: .82; }

/* Kolo 20: 🖨️ Tlačiť + 📷 Skenovať vedľa nadpisu každej obrazovky Check Listu; tlač = presne otvorený zoznam (#tasksView)
   bez shellu, pravého panela a nástrojov — viditeľnosť, nie display, aby tok strany ostal ako na obrazovke. */
.cl-surface-tools{ display: inline-flex; gap: 6px; align-items: center; margin: 0 0 6px; }
.cl-surface-tools .task-status-btn{ min-height: 28px; padding: 2px 10px; font-size: 12.5px; }
@media print{
  body.printing-checklist *{ visibility: hidden !important; }
  body.printing-checklist #tasksView, body.printing-checklist #tasksView *{ visibility: visible !important; }
  body.printing-checklist #tasksView{ position: absolute !important; left: 0; top: 0; width: 100% !important; margin: 0; padding: 8mm;
    background: #fff !important; color: #111 !important; }
  body.printing-checklist #tasksView .cl-rail, body.printing-checklist #tasksView .cl-rail *,
  body.printing-checklist #tasksView #clSurfaceTools, body.printing-checklist #tasksView #clSurfaceTools *,
  body.printing-checklist #tasksView #taskFab, body.printing-checklist #tasksView .cl-sticky-start,
  body.printing-checklist #tasksView .cl-sticky-start *{ display: none !important; }
  body.printing-checklist #tasksView .cl-calendar-sticky, body.printing-checklist #tasksView .sticky-header{ position: static !important; }
}

/* Kolo 21 (Richard 7. 9. 2026): reklamné vignety dodávateľov v PRAVOM PANELI Surovín — jedna pod druhou,
   šírka panela, menšie písmo; mriežka troch stĺpcov platí len tam, kde vignety ostali pod zoznamami. */
body.desktop-erp-active .desktop-erp-hub-aside .supplier-ads{ margin: 12px 0 0; }
body.desktop-erp-active .desktop-erp-hub-aside .supplier-ads-row{ grid-template-columns: minmax(0, 1fr); gap: 10px; }
body.desktop-erp-active .desktop-erp-hub-aside .supplier-ad{ padding: 10px 12px; }
body.desktop-erp-active .desktop-erp-hub-aside .supplier-ad-title{ font-size: 14px; }
body.desktop-erp-active .desktop-erp-hub-aside .supplier-ad-price{ font-size: 12px; }
body.desktop-erp-active .desktop-erp-hub-aside .supplier-ad-actions{ gap: 6px; margin-top: 8px; }
body.desktop-erp-active .desktop-erp-hub-aside .supplier-ad-actions .task-status-btn{ font-size: 11.5px; padding: 2px 8px; min-height: 26px; }
