/* ==========================================================================
   Jana Fitošová — design system
   ==========================================================================
   A quiet gallery: warm paper background, editorial serif headings, one clay
   accent, and images given room to carry the page.

   Fonts are system stacks on purpose. No webfont request means nothing leaves
   the visitor's browser to a third party (relevant under GDPR), the first
   paint has no flash of unstyled text, and there is no font file to ship.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */

:root {
  /* Warm neutrals — the paper the work hangs on */
  --stone-25:  #fdfcfa;
  --stone-50:  #faf8f5;
  --stone-100: #f3efe9;
  --stone-200: #e6e1da;
  --stone-300: #d3ccc2;
  --stone-400: #a8a096;
  --stone-500: #837b72;
  --stone-600: #635c55;
  --stone-700: #4a443e;
  --stone-800: #302c28;
  --stone-900: #1a1815;

  /* Clay — the single accent, used sparingly */
  --clay-50:  #fbf4f0;
  --clay-100: #f4e4db;
  --clay-200: #e7c6b5;
  --clay-300: #d5a288;
  --clay-400: #c07f5f;
  --clay-500: #a8623f;
  --clay-600: #8d4e30;
  --clay-700: #6f3d26;
  --clay-800: #522d1d;

  /* Semantic */
  --bg:            var(--stone-50);
  --bg-raised:     #ffffff;
  --bg-sunken:     var(--stone-100);
  --text:          var(--stone-900);
  --text-muted:    var(--stone-600);
  --text-subtle:   var(--stone-500);
  --border:        var(--stone-200);
  --border-strong: var(--stone-300);
  --accent:        var(--clay-500);
  --accent-hover:  var(--clay-600);
  --accent-soft:   var(--clay-50);

  /* Admin rail — graphite, not stone. The warm near-black that carries the
     public site turns muddy over a whole sidebar, so the admin gets its own
     neutral dark: it reads as a tool beside the paper, not as a brown wall. */
  --admin-bg:      #1e2227;
  --admin-line:    rgba(255, 255, 255, 0.07);
  --admin-text:    #9aa3ad;
  --admin-icon:    #6f7883;
  --admin-muted:   #6b747e;
  --admin-hover:   rgba(255, 255, 255, 0.055);
  --admin-active:  rgba(255, 255, 255, 0.1);

  --success: #4a6b4f;
  --success-soft: #eef3ee;
  --danger: #9b3d33;
  --danger-soft: #fbefee;
  --warning: #8a6420;
  --warning-soft: #fbf4e6;

  /* Type */
  --font-display: "Iowan Old Style", "Palatino Linotype", Palatino, Georgia,
                  "Times New Roman", serif;
  --font-body: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue",
               Arial, sans-serif;

  --text-xs:   0.75rem;
  --text-sm:   0.875rem;
  --text-base: 1rem;
  --text-lg:   1.125rem;
  --text-xl:   1.375rem;
  --text-2xl:  1.75rem;
  --text-3xl:  2.25rem;
  --text-4xl:  3rem;
  --text-5xl:  4rem;

  /* Space — 4px base */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.5rem;
  --space-6: 2rem;
  --space-7: 3rem;
  --space-8: 4rem;
  --space-9: 6rem;
  --space-10: 8rem;

  --radius-sm: 2px;
  --radius:    4px;
  --radius-lg: 8px;
  --radius-full: 999px;

  --shadow-sm: 0 1px 2px rgba(26, 24, 21, 0.05);
  --shadow:    0 4px 16px rgba(26, 24, 21, 0.07);
  --shadow-lg: 0 12px 40px rgba(26, 24, 21, 0.12);

  --ease: cubic-bezier(0.4, 0, 0.2, 1);
  --duration: 200ms;

  --container: 1240px;
  --container-narrow: 720px;
  --header-h: 76px;
}

/* --------------------------------------------------------------------------
   2. Reset
   -------------------------------------------------------------------------- */

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

* { margin: 0; }

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

body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

img, picture, svg, video {
  display: block;
  max-width: 100%;
  height: auto;
}

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

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

a { color: inherit; }

ul, ol { padding: 0; }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

::selection { background: var(--clay-200); color: var(--stone-900); }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* --------------------------------------------------------------------------
   3. Typography
   -------------------------------------------------------------------------- */

.display, .title, .subtitle, h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 400;
  line-height: 1.15;
  letter-spacing: -0.015em;
  color: var(--text);
  text-wrap: balance;
}

.display {
  font-size: clamp(2.5rem, 6vw, var(--text-5xl));
  line-height: 1.05;
  letter-spacing: -0.025em;
}

.title    { font-size: clamp(1.875rem, 4vw, var(--text-3xl)); }
.title-sm { font-size: var(--text-2xl); }
.subtitle {
  font-size: var(--text-xl);
  font-style: italic;
  color: var(--text-muted);
  line-height: 1.4;
  letter-spacing: -0.01em;
}

.eyebrow {
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-subtle);
}

.lede {
  font-size: var(--text-lg);
  color: var(--text-muted);
  line-height: 1.7;
  text-wrap: pretty;
}

.prose { max-width: 68ch; text-wrap: pretty; }
.prose p { margin-bottom: var(--space-4); }
.prose p:last-child { margin-bottom: 0; }
.prose a { color: var(--accent); text-underline-offset: 3px; }
.prose a:hover { color: var(--accent-hover); }
.prose h2 { font-size: var(--text-2xl); margin: var(--space-6) 0 var(--space-3); }
.prose h3 { font-size: var(--text-xl); margin: var(--space-5) 0 var(--space-2); }
.prose ul, .prose ol { margin: 0 0 var(--space-4) var(--space-5); }
.prose li { margin-bottom: var(--space-1); }

.muted  { color: var(--text-muted); }
.subtle { color: var(--text-subtle); }
.small  { font-size: var(--text-sm); }

/* --------------------------------------------------------------------------
   4. Layout
   -------------------------------------------------------------------------- */

.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--space-5);
}

.container-narrow { max-width: var(--container-narrow); }

.section { padding-block: var(--space-8); }
.section-lg { padding-block: var(--space-9); }
.section-sm { padding-block: var(--space-6); }

.section-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-6);
  flex-wrap: wrap;
}

.stack > * + * { margin-top: var(--space-4); }
.stack-sm > * + * { margin-top: var(--space-2); }
.stack-lg > * + * { margin-top: var(--space-6); }

.row {
  display: flex;
  gap: var(--space-3);
  align-items: center;
  flex-wrap: wrap;
}

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

@media (max-width: 900px) {
  .grid-3, .grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 560px) {
  .grid-2, .grid-3, .grid-4 { grid-template-columns: minmax(0, 1fr); }
}

main { flex: 1 0 auto; }

.divider { height: 1px; background: var(--border); border: 0; }

/* --------------------------------------------------------------------------
   5. Button — hierarchy × size, after Untitled UI
   -------------------------------------------------------------------------- */

.btn {
  --btn-bg: transparent;
  --btn-fg: var(--text);
  --btn-border: transparent;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: 0.625rem 1.125rem;
  font-size: var(--text-sm);
  font-weight: 500;
  line-height: 1.4;
  text-decoration: none;
  white-space: nowrap;
  border: 1px solid var(--btn-border);
  border-radius: var(--radius);
  background: var(--btn-bg);
  color: var(--btn-fg);
  cursor: pointer;
  transition: background var(--duration) var(--ease),
              border-color var(--duration) var(--ease),
              color var(--duration) var(--ease),
              opacity var(--duration) var(--ease);
}

.btn:disabled, .btn[aria-disabled="true"] {
  opacity: 0.5;
  pointer-events: none;
}

.btn-primary   { --btn-bg: var(--stone-900); --btn-fg: #fff; --btn-border: var(--stone-900); }
.btn-primary:hover { --btn-bg: var(--stone-800); --btn-border: var(--stone-800); }

.btn-accent    { --btn-bg: var(--accent); --btn-fg: #fff; --btn-border: var(--accent); }
.btn-accent:hover { --btn-bg: var(--accent-hover); --btn-border: var(--accent-hover); }

.btn-secondary { --btn-bg: var(--bg-raised); --btn-fg: var(--text); --btn-border: var(--border-strong); }
.btn-secondary:hover { --btn-bg: var(--stone-100); }

.btn-tertiary  { --btn-fg: var(--text-muted); }
.btn-tertiary:hover { --btn-bg: var(--stone-100); --btn-fg: var(--text); }

.btn-danger    { --btn-bg: var(--danger); --btn-fg: #fff; --btn-border: var(--danger); }
.btn-danger:hover { opacity: 0.88; }

.btn-link {
  padding: 0;
  border: 0;
  --btn-fg: var(--accent);
  text-decoration: underline;
  text-underline-offset: 4px;
  text-decoration-thickness: 1px;
}
.btn-link:hover { --btn-fg: var(--accent-hover); }

.btn-sm { padding: 0.4375rem 0.875rem; font-size: var(--text-xs); }
.btn-lg { padding: 0.8125rem 1.5rem; font-size: var(--text-base); }
.btn-xl { padding: 1rem 2rem; font-size: var(--text-lg); }
.btn-block { display: flex; width: 100%; }

.btn svg { width: 1.125em; height: 1.125em; flex: none; }

/* --------------------------------------------------------------------------
   6. Badge
   -------------------------------------------------------------------------- */

.badge {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  padding: 0.1875rem 0.625rem;
  font-size: var(--text-xs);
  font-weight: 500;
  line-height: 1.5;
  border-radius: var(--radius-full);
  background: var(--stone-100);
  color: var(--text-muted);
  border: 1px solid var(--border);
  white-space: nowrap;
}

.badge-available { background: var(--success-soft); color: var(--success); border-color: transparent; }
.badge-reserved  { background: var(--warning-soft); color: var(--warning); border-color: transparent; }
.badge-sold      { background: var(--stone-200); color: var(--stone-600); border-color: transparent; }
.badge-accent    { background: var(--accent-soft); color: var(--accent); border-color: transparent; }
.badge-new       { background: var(--danger-soft); color: var(--danger); border-color: transparent; }

.badge-dot::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
  flex: none;
}

/* The gap above always implied a badge might hold an icon, but nothing sized
   one: outside a button an inline SVG has no intrinsic size and fills the line.
   Scaled to the text so it reads as part of the label, not next to it. */
.badge svg {
  width: 0.875em;
  height: 0.875em;
  flex: none;
  stroke-width: 2.5;
}

/* A badge that is also a link. It states where something is and offers to take
   you there, so it stays a quiet pill rather than picking up link underlines. */
.badge-link {
  text-decoration: none;
  transition: background-color var(--duration) var(--ease);
}

.badge-link:hover {
  background: var(--clay-100);
}

/* --------------------------------------------------------------------------
   7. Card & surfaces
   -------------------------------------------------------------------------- */

.card {
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
}

.card-flush { padding: 0; overflow: hidden; }
.card-head {
  padding: var(--space-4) var(--space-5);
  border-bottom: 1px solid var(--border);
}
.card-body { padding: var(--space-5); }

/* --------------------------------------------------------------------------
   8. Product card
   -------------------------------------------------------------------------- */

.product-card {
  display: flex;
  flex-direction: column;
  text-decoration: none;
  color: inherit;
  group: card;
}

.product-card__frame {
  position: relative;
  overflow: hidden;
  background: var(--stone-100);
  border-radius: var(--radius);
  aspect-ratio: 4 / 5;
}

.product-card__frame img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 600ms var(--ease);
}

.product-card:hover .product-card__frame img { transform: scale(1.03); }

.product-card__badge {
  position: absolute;
  top: var(--space-3);
  left: var(--space-3);
}

.product-card__body { padding-top: var(--space-3); }

.product-card__title {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  line-height: 1.3;
  letter-spacing: -0.01em;
}

.product-card__meta {
  font-size: var(--text-sm);
  color: var(--text-subtle);
  margin-top: 0.125rem;
}

/* Price sits below the category and carries the weight the meta line does not,
   so the eye lands on the title, then the price. */
.product-card__price {
  font-size: var(--text-sm);
  color: var(--text);
  margin-top: 0.375rem;
}

/* An unopened message. The marker is a bar on the leading edge rather than a
   background wash, so it survives the row's hover and selected states and does
   not fight the status badge for attention. */
.table tr.is-unread td:first-child {
  box-shadow: inset 3px 0 0 0 var(--accent);
}

.table tr.is-unread td a {
  font-weight: 600;
}

/* When and where a news item happens. Only rendered for actual events, so it
   can afford to stand out from the body copy. */
.event-note {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0.75rem;
  font-size: var(--text-sm);
  color: var(--text);
}

.event-note svg {
  flex: none;
  color: var(--text-subtle);
}

.product-card__placeholder {
  width: 100%;
  height: 100%;
  display: grid;
  place-items: center;
  color: var(--stone-400);
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  font-style: italic;
}

/* --------------------------------------------------------------------------
   9. Forms
   -------------------------------------------------------------------------- */

.field { display: block; margin-bottom: var(--space-4); }

.label {
  display: block;
  font-size: var(--text-sm);
  font-weight: 500;
  margin-bottom: var(--space-2);
  color: var(--text);
}

.label .req { color: var(--danger); }

.input, .textarea, .select {
  width: 100%;
  padding: 0.625rem 0.875rem;
  font-size: var(--text-base);
  background: var(--bg-raised);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  color: var(--text);
  transition: border-color var(--duration) var(--ease),
              box-shadow var(--duration) var(--ease);
}

.input::placeholder, .textarea::placeholder { color: var(--stone-400); }

.input:focus, .textarea:focus, .select:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--clay-100);
}

.textarea { min-height: 8rem; resize: vertical; line-height: 1.6; }

.select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='none' stroke='%23837b72' stroke-width='1.5' d='M1 1.5 6 6.5l5-5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.875rem center;
  padding-right: 2.25rem;
}

.input-error, .textarea-error, .select-error { border-color: var(--danger); }
.input-error:focus { box-shadow: 0 0 0 3px var(--danger-soft); }

.hint  { font-size: var(--text-sm); color: var(--text-subtle); margin-top: var(--space-1); }
.hint-inline { margin-top: 0; }
.hint svg { width: 1.125rem; height: 1.125rem; flex: none; }

/* Baseline size for every icon ui_icon() emits.
   The icons ship with a viewBox and no width or height, and the reset gives
   svg `max-width: 100%` with `height: auto`, so without this an icon grows to
   the width of its container instead of staying an icon. Context rules like
   `.btn svg` are one specificity point higher and still win, so this only
   catches the places nobody thought to style. */
.icon { width: 1.125rem; height: 1.125rem; flex: none; }

/* The close control is a 2.75rem target, so its glyph gets a little more room
   than the baseline. */
.lightbox__close svg { width: 1.25rem; height: 1.25rem; }
.error { font-size: var(--text-sm); color: var(--danger); margin-top: var(--space-1); }

.checkbox {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  cursor: pointer;
  font-size: var(--text-sm);
  line-height: 1.5;
}

.checkbox input {
  width: 1.0625rem;
  height: 1.0625rem;
  margin: 0.1875rem 0 0;
  accent-color: var(--accent);
  flex: none;
  cursor: pointer;
}

/* Honeypot: present for bots, invisible and unreachable for people. */
.hp {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* --------------------------------------------------------------------------
   10. Alert
   -------------------------------------------------------------------------- */

.alert {
  display: flex;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius);
  border: 1px solid transparent;
  font-size: var(--text-sm);
  line-height: 1.55;
}

.alert-success { background: var(--success-soft); color: var(--success); }
.alert-error   { background: var(--danger-soft);  color: var(--danger); }
.alert-info    { background: var(--stone-100);    color: var(--text-muted); }
.alert-warning { background: var(--warning-soft); color: var(--warning); }

.alert strong { font-weight: 600; }

/* --------------------------------------------------------------------------
   11. Header & navigation
   -------------------------------------------------------------------------- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(250, 248, 245, 0.88);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid transparent;
  transition: border-color var(--duration) var(--ease);
}

.site-header.is-scrolled { border-bottom-color: var(--border); }

.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-5);
  min-height: var(--header-h);
}

.brand { display: flex; align-items: center; text-decoration: none; flex: none; }
/* The wordmark is a fine-stroked script, so it needs a little more height than
   a geometric logo would to stay legible. */
.brand img { height: 42px; width: auto; }
@media (max-width: 480px) { .brand img { height: 34px; } }
.brand__fallback {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-style: italic;
  letter-spacing: -0.01em;
}

.nav { display: flex; align-items: center; gap: var(--space-5); list-style: none; }

.nav a {
  font-size: var(--text-sm);
  text-decoration: none;
  color: var(--text-muted);
  padding-block: var(--space-2);
  position: relative;
  transition: color var(--duration) var(--ease);
}

.nav a:hover { color: var(--text); }

.nav a[aria-current="page"] { color: var(--text); }
.nav a[aria-current="page"]::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0.25rem;
  height: 1px;
  background: var(--accent);
}

/* The language switcher is a nav item, but not a page: it changes what you are
   reading rather than where you are. A hairline separator and a boxed two
   letter label set it apart without adding a second row of chrome. */
.nav__lang { padding-left: var(--space-5); border-left: 1px solid var(--border); }

.nav__lang a {
  font-size: var(--text-xs);
  letter-spacing: 0.08em;
  padding: 0.25rem var(--space-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  line-height: 1.4;
}

.nav__lang a:hover { border-color: var(--accent); color: var(--accent); }

.nav-toggle { display: none; order: 1; padding: var(--space-2); margin-right: calc(var(--space-2) * -1); }
.nav-toggle svg { width: 24px; height: 24px; }

@media (max-width: 860px) {
  .nav-toggle { display: block; }

  /* The menu is a sheet dropped from under the header, not a list glued to it.
     Rows are sized for a thumb, separated by hairlines so each one reads as its
     own target, and the sheet scrolls on its own if the list ever outgrows a
     short screen in landscape. */
  .nav {
    position: fixed;
    inset: var(--header-h) 0 auto;
    z-index: 60;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    background: var(--bg);
    border-bottom: 1px solid var(--border);
    /* dvh, not vh: mobile browser chrome shrinks the viewport as it hides and
       vh does not follow, which leaves the sheet taller than the screen. */
    max-height: calc(100dvh - var(--header-h));
    overflow-y: auto;
    overscroll-behavior: contain;
    /* Room for the home indicator on a notched phone. */
    padding: var(--space-2) 0 calc(var(--space-4) + env(safe-area-inset-bottom));
    box-shadow: var(--shadow-lg);
    display: none;
  }

  .nav.is-open {
    display: flex;
    animation: nav-drop 220ms var(--ease);
  }

  @keyframes nav-drop {
    from { opacity: 0; transform: translateY(-0.5rem); }
    to   { opacity: 1; transform: translateY(0); }
  }

  .nav li + li { border-top: 1px solid var(--border); }

  /* In the sheet the switcher is just another row: the desktop separator and
     the boxed label would fight the full-width layout. */
  .nav__lang { padding-left: 0; border-left: 0; }

  .nav__lang a {
    font-size: var(--text-lg);
    letter-spacing: 0;
    padding: var(--space-2) var(--space-5);
    border: 0;
    border-radius: 0;
  }

  .nav a {
    display: flex;
    align-items: center;
    /* 3.25rem clears the 44px minimum for a touch target with room to spare. */
    min-height: 3.25rem;
    padding: var(--space-2) var(--space-5);
    font-size: var(--text-lg);
    color: var(--text);
    /* The clay bar marks the current page. It is transparent rather than absent
       so the label does not shift sideways when the page changes. */
    border-left: 2px solid transparent;
  }

  .nav a:active { background: var(--stone-100); }

  .nav a[aria-current="page"] {
    border-left-color: var(--accent);
    background: var(--accent-soft);
    font-weight: 500;
  }

  /* The desktop underline would sit under a row that is now full width. */
  .nav a[aria-current="page"]::after { display: none; }

  /* Dims the page behind the sheet, so the menu reads as a layer rather than
     as part of the article. Purely decorative: where :has() is unsupported the
     menu simply opens without the dimming.

     Hung off body, not off the header. The header carries backdrop-filter,
     which makes it a containing block for fixed-position descendants, so a
     backdrop placed there is measured against the 77px header instead of the
     viewport and collapses to nothing.

     The z-index sits below the header's 50, not above it. The header is a
     stacking context of its own, so the sheet's z-index only ranks it inside
     the header: anything above 50 covers the menu along with the page. */
  body:has(.nav.is-open)::after {
    content: "";
    position: fixed;
    inset: var(--header-h) 0 0;
    z-index: 40;
    background: rgba(26, 24, 21, 0.32);
    animation: nav-fade 220ms var(--ease);
  }

  @keyframes nav-fade {
    from { opacity: 0; }
    to   { opacity: 1; }
  }
}

/* A phone held sideways has almost no height to give: drop the row height back
   so the whole menu still fits without scrolling. */
@media (max-width: 860px) and (max-height: 460px) {
  .nav a { min-height: 2.75rem; font-size: var(--text-base); }
}

/* --------------------------------------------------------------------------
   12. Footer
   -------------------------------------------------------------------------- */

.site-footer {
  margin-top: var(--space-9);
  padding-block: var(--space-7) var(--space-5);
  border-top: 1px solid var(--border);
  background: var(--stone-25);
}

.site-footer__grid {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr;
  gap: var(--space-6);
  margin-bottom: var(--space-7);
}

@media (max-width: 760px) {
  .site-footer__grid { grid-template-columns: 1fr; gap: var(--space-5); }
}

.footer-heading {
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-subtle);
  margin-bottom: var(--space-3);
}

.footer-list { list-style: none; }
.footer-list li + li { margin-top: var(--space-2); }
.footer-list a {
  font-size: var(--text-sm);
  color: var(--text-muted);
  text-decoration: none;
}
.footer-list a:hover { color: var(--text); text-decoration: underline; text-underline-offset: 3px; }

.site-footer__bottom {
  display: flex;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
  padding-top: var(--space-4);
  border-top: 1px solid var(--border);
  font-size: var(--text-xs);
  color: var(--text-subtle);
}

.social { display: flex; gap: var(--space-3); list-style: none; }
.social a {
  display: grid;
  place-items: center;
  width: 2.25rem;
  height: 2.25rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-full);
  color: var(--text-muted);
  transition: all var(--duration) var(--ease);
}
.social a:hover { color: var(--text); border-color: var(--border-strong); background: var(--bg-raised); }
.social svg { width: 1.0625rem; height: 1.0625rem; }

/* --------------------------------------------------------------------------
   13. Breadcrumbs & pagination
   -------------------------------------------------------------------------- */

.breadcrumbs {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  list-style: none;
  font-size: var(--text-sm);
  color: var(--text-subtle);
  margin-bottom: var(--space-5);
}

.breadcrumbs a { text-decoration: none; color: var(--text-subtle); }
.breadcrumbs a:hover { color: var(--text); }
.breadcrumbs li + li::before { content: "/"; margin-right: var(--space-2); color: var(--stone-300); }

.pagination {
  display: flex;
  justify-content: center;
  gap: var(--space-2);
  list-style: none;
  margin-top: var(--space-7);
}

.pagination a, .pagination span {
  display: grid;
  place-items: center;
  min-width: 2.5rem;
  height: 2.5rem;
  padding-inline: var(--space-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  font-size: var(--text-sm);
  text-decoration: none;
  color: var(--text-muted);
  background: var(--bg-raised);
}

.pagination a:hover { border-color: var(--border-strong); color: var(--text); }
.pagination [aria-current="page"] {
  background: var(--stone-900);
  border-color: var(--stone-900);
  color: #fff;
}
.pagination .is-disabled { opacity: 0.4; pointer-events: none; }

/* --------------------------------------------------------------------------
   14. Empty state
   -------------------------------------------------------------------------- */

.empty {
  text-align: center;
  padding: var(--space-8) var(--space-5);
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius-lg);
  color: var(--text-muted);
}

.empty__title {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  color: var(--text);
  margin-bottom: var(--space-2);
}

/* --------------------------------------------------------------------------
   15. Product detail
   -------------------------------------------------------------------------- */

.product-detail {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
  gap: var(--space-8);
  align-items: start;
}

@media (max-width: 940px) {
  .product-detail { grid-template-columns: minmax(0, 1fr); gap: var(--space-6); }
}

/* A fixed frame, the same shape as the product-card thumbnail, so the layout
   holds still while browsing between portrait and landscape photos. The
   lightbox this opens into is unconstrained and shows the photo in full. */
.gallery__main {
  position: relative;
  display: block;
  background: var(--stone-100);
  border-radius: var(--radius);
  overflow: hidden;
  aspect-ratio: 4 / 5;
  cursor: zoom-in;
}

.gallery__main img { width: 100%; height: 100%; object-fit: cover; }

.gallery__thumbs {
  display: flex;
  gap: var(--space-2);
  margin-top: var(--space-2);
  flex-wrap: wrap;
}

.gallery__thumb {
  width: 5rem;
  height: 5rem;
  border-radius: var(--radius-sm);
  overflow: hidden;
  border: 1px solid var(--border);
  background: var(--stone-100);
  padding: 0;
  cursor: pointer;
  transition: border-color var(--duration) var(--ease);
}

.gallery__thumb img { width: 100%; height: 100%; object-fit: cover; }
.gallery__thumb[aria-selected="true"] { border-color: var(--stone-900); }

.product-info { position: sticky; top: calc(var(--header-h) + var(--space-5)); }

@media (max-width: 940px) {
  .product-info { position: static; }
}

.specs { width: 100%; border-collapse: collapse; font-size: var(--text-sm); }
.specs th, .specs td {
  text-align: left;
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--border);
  vertical-align: top;
}
.specs th { font-weight: 500; color: var(--text-subtle); width: 40%; }
.specs tr:last-child th, .specs tr:last-child td { border-bottom: 0; }

/* Lightbox with pinch/scroll zoom */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 100;
  background: rgba(26, 24, 21, 0.94);
  display: none;
  place-items: center;
  padding: var(--space-5);
}

.lightbox.is-open { display: grid; }
.lightbox__stage { overflow: auto; max-width: 100%; max-height: 100%; cursor: zoom-in; }
.lightbox__stage img {
  max-width: 100%;
  max-height: 88vh;
  transition: transform 300ms var(--ease);
  transform-origin: center center;
}
.lightbox__stage.is-zoomed { cursor: zoom-out; }
.lightbox__stage.is-zoomed img { max-width: none; max-height: none; transform: scale(2); }

.lightbox__close {
  position: absolute;
  top: var(--space-4);
  right: var(--space-4);
  width: 2.75rem;
  height: 2.75rem;
  display: grid;
  place-items: center;
  border-radius: var(--radius-full);
  background: rgba(255, 255, 255, 0.1);
  color: #fff;
}
.lightbox__close:hover { background: rgba(255, 255, 255, 0.2); }

/* --------------------------------------------------------------------------
   16. Hero
   -------------------------------------------------------------------------- */

.hero { padding-block: var(--space-9) var(--space-8); }

.hero__inner {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.9fr);
  gap: var(--space-8);
  align-items: center;
}

@media (max-width: 900px) {
  .hero { padding-block: var(--space-7) var(--space-6); }
  .hero__inner { grid-template-columns: minmax(0, 1fr); gap: var(--space-6); }
}

.hero__figure {
  aspect-ratio: 4 / 5;
  background: var(--stone-100);
  border-radius: var(--radius);
  overflow: hidden;
}
.hero__figure img { width: 100%; height: 100%; object-fit: cover; }

/* --------------------------------------------------------------------------
   17. Category tiles
   -------------------------------------------------------------------------- */

.category-tile {
  position: relative;
  display: block;
  aspect-ratio: 3 / 4;
  border-radius: var(--radius);
  overflow: hidden;
  text-decoration: none;
  background: var(--stone-200);
}

.category-tile img {
  width: 100%; height: 100%; object-fit: cover;
  transition: transform 700ms var(--ease);
}
.category-tile:hover img { transform: scale(1.04); }

.category-tile__overlay {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: var(--space-5);
  background: linear-gradient(to top, rgba(26, 24, 21, 0.72), rgba(26, 24, 21, 0.05) 55%);
  color: #fff;
}

.category-tile__name {
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  line-height: 1.1;
}

.category-tile__count { font-size: var(--text-sm); opacity: 0.85; margin-top: 0.125rem; }

/* --------------------------------------------------------------------------
   18. Tables (admin)
   -------------------------------------------------------------------------- */

.table-wrap { overflow-x: auto; border: 1px solid var(--border); border-radius: var(--radius-lg); background: var(--bg-raised); }

.table { width: 100%; border-collapse: collapse; font-size: var(--text-sm); }

.table th {
  text-align: left;
  font-weight: 500;
  color: var(--text-subtle);
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border);
  background: var(--stone-25);
  white-space: nowrap;
}

.table td {
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
}

.table tr:last-child td { border-bottom: 0; }

/* Actions read as one group on a single line. Aligned from the left, not the
   right: only some rows carry a second item, and pushing the group right would
   move "Upraviť" between rows depending on what sits beside it. The primary
   action stays in one column down the whole table. */
.table__actions {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  white-space: nowrap;
}

/* The drafting helper sits inside the Texty card but is not part of the piece:
   nothing typed in it is saved. The inset background says so without a label
   having to. */
.ai-box {
  background: var(--bg-sunken);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
}

.ai-box > * + * { margin-top: var(--space-3); }

/* "Upraviť" starts at the same place on every row, and whatever follows it is
   pushed to the far edge instead of trailing right behind it. Both ends then
   line up down the table, and the status stops reading as part of the button.
   The column is as wide as its widest row, so the right edge is a real one. */
.table__actions > :last-child:not(:first-child) {
  margin-left: auto;
}
.table tbody tr:hover { background: var(--stone-25); }

.table__thumb {
  width: 3rem; height: 3rem;
  object-fit: cover;
  border-radius: var(--radius-sm);
  background: var(--stone-100);
}

/* --------------------------------------------------------------------------
   19. Admin shell
   -------------------------------------------------------------------------- */

.admin { display: grid; grid-template-columns: 248px minmax(0, 1fr); min-height: 100vh; }

/* Stacked, the two auto rows would otherwise split the leftover height between
   them and leave the page starting halfway down. The bar takes what it needs
   and the content takes the rest. */
@media (max-width: 900px) {
  .admin { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr); }
}

/* The rail stays put while a long table scrolls past it, so the menu is never
   somewhere above the fold you have to go back for. */
.admin__side {
  background: var(--admin-bg);
  color: var(--admin-text);
  padding: var(--space-5) var(--space-3) var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  position: sticky;
  top: 0;
  align-self: start;
  height: 100vh;
  overflow-y: auto;
}

/* Clay is too dark to read against the rail, so focus and the active marker
   take the lighter tint of the same accent. */
.admin__side :focus-visible { outline-color: var(--clay-300); }

.admin__brand {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 0 var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--admin-line);
  text-decoration: none;
}

.admin__brand strong {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-style: italic;
  font-weight: 400;
  color: #fff;
}

.admin__brand span {
  font-size: var(--text-xs);
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--admin-muted);
}

.admin__menu { display: flex; flex-direction: column; gap: var(--space-5); }

.admin__label {
  padding: 0 var(--space-3);
  margin-bottom: var(--space-2);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--admin-muted);
}

.admin__nav { list-style: none; display: flex; flex-direction: column; gap: 1px; }

.admin__nav a,
.admin__nav button {
  position: relative;
  width: 100%;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: 0.5rem var(--space-3);
  border-radius: var(--radius);
  font: inherit;
  font-size: var(--text-sm);
  text-align: left;
  color: var(--admin-text);
  text-decoration: none;
  transition: background var(--duration) var(--ease), color var(--duration) var(--ease);
}

.admin__nav span { flex: 1; }
.admin__nav .admin__count { flex: none; }

.admin__nav svg {
  width: 1.125rem;
  height: 1.125rem;
  flex: none;
  color: var(--admin-icon);
  transition: color var(--duration) var(--ease);
}

.admin__nav a:hover,
.admin__nav button:hover { background: var(--admin-hover); color: #fff; }
.admin__nav a:hover svg,
.admin__nav button:hover svg { color: inherit; }

/* The open section keeps the accent on its own left edge — a stripe against the
   window edge would read as a stray line, this reads as part of the item. */
.admin__nav a[aria-current="page"] {
  background: var(--admin-active);
  color: #fff;
  box-shadow: inset 2px 0 0 var(--clay-300);
}

.admin__nav a[aria-current="page"] svg { color: var(--clay-300); }

/* Unread messages are the one number worth a colour in here. */
.admin__count {
  flex: none;
  min-width: 1.25rem;
  height: 1.25rem;
  padding: 0 0.375rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-full);
  background: var(--clay-300);
  color: var(--stone-900);
  font-size: 0.6875rem;
  font-weight: 600;
}

.admin__foot {
  margin-top: auto;
  padding-top: var(--space-4);
  border-top: 1px solid var(--admin-line);
}

.admin__main { padding: var(--space-6) var(--space-6) var(--space-9); min-width: 0; }

/* Stacked, the rail becomes a bar: brand on the left, sections wrapping after
   it, the way a top navigation would sit anyway. */
@media (max-width: 900px) {
  .admin__side {
    position: static;
    height: auto;
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2) var(--space-4);
    padding: var(--space-4);
    border-bottom: 1px solid var(--admin-line);
  }

  /* Brand and the two account links share the top line, the sections take the
     one below, so the bar is two rows rather than three. */
  .admin__brand { order: 1; padding: 0; border-bottom: 0; }
  .admin__foot { order: 2; margin: 0 0 0 auto; padding-top: 0; border-top: 0; }
  .admin__menu { order: 3; flex-basis: 100%; flex-direction: row; flex-wrap: wrap; gap: var(--space-2); }
  .admin__label { display: none; }
  .admin__nav { flex-direction: row; flex-wrap: wrap; }
}

/* On a phone the sections would wrap into a ragged block, so they keep one line
   and that line scrolls sideways instead. */
@media (max-width: 640px) {
  .admin__main { padding: var(--space-5) var(--space-4) var(--space-8); }

  .admin__side { padding-right: 0; }
  .admin__menu {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    padding-right: var(--space-4);
  }
  .admin__menu::-webkit-scrollbar { display: none; }
  .admin__nav { flex-wrap: nowrap; }
  .admin__nav a,
  .admin__nav button { white-space: nowrap; }
  .admin__foot { padding-right: var(--space-4); }
}

.admin__head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
  margin-bottom: var(--space-5);
}

.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: var(--space-4); }

.stat { background: var(--bg-raised); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: var(--space-4); }
.stat__value { font-family: var(--font-display); font-size: var(--text-3xl); line-height: 1; }
.stat__label { font-size: var(--text-sm); color: var(--text-subtle); margin-top: var(--space-2); }

.form-grid { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); gap: var(--space-6); align-items: start; }

@media (max-width: 900px) { .form-grid { grid-template-columns: minmax(0, 1fr); } }

/* A parameter is four fields now: the Slovak label and value, then the same
   pair in English. Two columns rather than four across, so each language reads
   as its own line and the inputs stay wide enough to see what is in them. The
   remove button sits in its own column spanning both rows. */
.spec-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr) auto;
  gap: var(--space-2);
  margin-bottom: var(--space-4);
  padding-bottom: var(--space-4);
  border-bottom: 1px solid var(--border);
}
.spec-row:last-child { border-bottom: 0; }
.spec-row .btn { align-self: start; grid-row: 1 / span 2; grid-column: 3; }

@media (max-width: 700px) {
  .spec-row { grid-template-columns: minmax(0, 1fr); }
  .spec-row .btn { grid-row: auto; grid-column: 1; justify-self: start; }
}

.media-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: var(--space-3); }
.media-item { position: relative; border-radius: var(--radius); overflow: hidden; border: 1px solid var(--border); background: var(--stone-100); }
.media-item img { width: 100%; aspect-ratio: 1; object-fit: cover; }
.media-item form { position: absolute; top: var(--space-2); right: var(--space-2); }

.upload-preview { margin-top: var(--space-4); }

/* A category's image is cropped to the same 3:4 tile on the home page, so its
   admin preview — both the saved image and the one picked but not yet
   uploaded — is boxed the same way rather than the square every other
   image preview in the admin uses, and shows the actual crop up front. */
.category-image-preview {
  width: 10rem;
  aspect-ratio: 3 / 4;
  border-radius: var(--radius);
  overflow: hidden;
  border: 1px solid var(--border);
  background: var(--stone-100);
}

.category-image-preview img { width: 100%; height: 100%; object-fit: cover; }

#image + .upload-preview .media-grid { grid-template-columns: 10rem; }
#image + .upload-preview .media-item img { aspect-ratio: 3 / 4; }

.upload-preview__remove {
  position: absolute;
  top: var(--space-1);
  right: var(--space-1);
  width: 1.5rem;
  height: 1.5rem;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-full);
  background: rgba(26, 24, 21, 0.7);
  color: #fff;
  line-height: 1;
  font-size: var(--text-base);
}

.upload-preview__remove:hover { background: rgba(26, 24, 21, 0.9); }

/* A trigger and a small panel that pops up from it — the shape shared by a
   row's kebab menu and a toolbar's filter dropdown. The panel is positioned
   in JS with position: fixed, computed from the trigger's own rect, so it
   escapes any scrolling ancestor (.table-wrap scrolls horizontally) instead
   of being clipped by it or scrolling away with whatever opened it. */
.popover { position: relative; display: inline-flex; }

.popover__panel {
  position: fixed;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  z-index: 200;
}

.popover__panel[hidden] { display: none; }
.popover__panel form { margin: 0; }

.row-menu__trigger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  border-radius: var(--radius);
  color: var(--text-muted);
}

.row-menu__trigger:hover,
.row-menu__trigger[aria-expanded="true"] { background: var(--stone-100); color: var(--text); }

.row-menu__trigger svg { width: 1.125rem; height: 1.125rem; }

.row-menu__panel {
  min-width: 11rem;
  padding: var(--space-2);
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.row-menu__item {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  width: 100%;
  padding: 0.5rem var(--space-3);
  border-radius: var(--radius);
  font: inherit;
  font-size: var(--text-sm);
  text-align: left;
  text-decoration: none;
  color: var(--text);
}

.row-menu__item:hover { background: var(--stone-100); }
.row-menu__item svg { width: 1rem; height: 1rem; color: var(--text-muted); flex: none; }

.row-menu__item--danger { color: var(--danger); }
.row-menu__item--danger svg { color: var(--danger); }
.row-menu__item--danger:hover { background: var(--danger-soft); }

/* Toolbar: a search bar with a small filter tucked beside it, everything on
   one baseline. The search input carries no visible label — a select with a
   label above it sits taller than a button next to it, which is exactly the
   misalignment this replaces. */
.toolbar {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
}

.toolbar__search {
  position: relative;
  flex: 1;
  min-width: 12rem;
  display: flex;
  align-items: center;
}

/* The magnifying glass doubles as the submit button — a lone text input in a
   form with no button of its own cannot be relied on to submit on Enter, so
   this is what actually makes the search bar work, not just decoration. */
.toolbar__search-submit {
  position: absolute;
  left: 0.875rem;
  display: flex;
  color: var(--text-subtle);
}

.toolbar__search-submit:hover { color: var(--text); }
.toolbar__search-submit svg { width: 1.125rem; height: 1.125rem; }

.toolbar__search input {
  width: 100%;
  padding: 0.625rem 0.875rem 0.625rem 2.625rem;
  font-size: var(--text-base);
  background: var(--bg-raised);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  color: var(--text);
}

.toolbar__search input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--clay-100);
}

/* The native clear (×) a type="search" input grows once it has a value. */
.toolbar__search input::-webkit-search-cancel-button { margin-right: -0.25rem; }

.filter-menu__trigger {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  height: 2.75rem;
  padding: 0 var(--space-4);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--text);
  background: var(--bg-raised);
}

.filter-menu__trigger:hover,
.filter-menu__trigger[aria-expanded="true"] { background: var(--stone-100); }

.filter-menu__trigger svg { width: 1.125rem; height: 1.125rem; color: var(--text-muted); }

.filter-menu__dot {
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: var(--accent);
}

/* The options list borrows .row-menu__panel/.row-menu__item wholesale (see
   above) so a filter choice is exactly as tall as a row's own menu item —
   one row height, defined once, instead of a second copy to keep in sync. */
.filter-menu__panel { min-width: 12rem; }

.filter-menu__option--active { color: var(--text); font-weight: 500; }
.filter-menu__option--active svg { color: var(--accent); }

/* --------------------------------------------------------------------------
   20. Utilities
   -------------------------------------------------------------------------- */

.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  left: var(--space-4);
  top: calc(var(--space-4) * -4);
  z-index: 100;
  padding: var(--space-2) var(--space-4);
  background: var(--stone-900);
  color: #fff;
  border-radius: var(--radius);
  text-decoration: none;
  transition: top var(--duration) var(--ease);
}
.skip-link:focus { top: var(--space-4); }

.text-center { text-align: center; }
.mt-0 { margin-top: 0; }
.mt-4 { margin-top: var(--space-4); }
.mt-6 { margin-top: var(--space-6); }
.mb-0 { margin-bottom: 0; }
.mb-4 { margin-bottom: var(--space-4); }
.mb-6 { margin-bottom: var(--space-6); }
.ml-auto { margin-left: auto; }
.flex-1 { flex: 1; }

@media print {
  .site-header, .site-footer, .btn, .nav { display: none !important; }
  body { background: #fff; }
}

/* Two legal links now sit where one used to: terms and the privacy notice.
   They wrap onto their own line on a phone rather than crowding the copyright. */
.site-footer__legal { display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-5); }

/* --------------------------------------------------------------------------
   Shop: cart link, cart page, checkout choices
   -------------------------------------------------------------------------- */
.text-right { text-align: right; }

/* The cart icon sits with the language switcher at the end of the nav. The
   count is a small pill; hidden entirely when the cart is empty so the icon
   does not read as "0 things to do". */
.nav__cart a { display: inline-flex; align-items: center; gap: var(--space-1); }
.nav__cart svg { width: 20px; height: 20px; }
.nav__cart a[aria-current="page"]::after { display: none; }
.nav__cart-count {
  min-width: 1.25rem;
  height: 1.25rem;
  padding: 0 0.35rem;
  border-radius: 999px;
  background: var(--accent);
  color: #fff;
  font-size: var(--text-xs);
  font-weight: 600;
  line-height: 1.25rem;
  text-align: center;
}

/* Icon only on the desktop bar, icon and word in the mobile sheet. */
.nav__cart-label {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

@media (max-width: 860px) {
  .nav__cart a { padding: var(--space-3) var(--space-5); font-size: var(--text-lg); gap: var(--space-2); }
  .nav__cart-label { position: static; width: auto; height: auto; margin: 0; overflow: visible; clip: auto; }
}

/* One row per piece: thumbnail, title, price, remove. */
.cart { padding: 0; }
.cart-line {
  display: grid;
  grid-template-columns: 4.5rem minmax(0, 1fr) auto auto;
  gap: var(--space-4);
  align-items: center;
  padding: var(--space-4) var(--space-5);
  border-bottom: 1px solid var(--border);
}
.cart-line__thumb {
  display: block;
  width: 4.5rem;
  aspect-ratio: 1;
  background: var(--bg-sunken);
  border-radius: var(--radius);
  overflow: hidden;
}
.cart-line__thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.cart-line__title { font-family: var(--font-display); font-size: var(--text-lg); text-decoration: none; color: var(--text); }
.cart-line__title:hover { color: var(--accent); }
.cart-line__price { font-variant-numeric: tabular-nums; white-space: nowrap; }
.cart-line__remove { margin: 0; }
.cart-summary { padding: var(--space-4) var(--space-5); }
.cart-summary__row { display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-4); font-size: var(--text-lg); }

@media (max-width: 600px) {
  .cart-line { grid-template-columns: 3.5rem minmax(0, 1fr); }
  .cart-line__thumb { width: 3.5rem; }
  .cart-line__price, .cart-line__remove { grid-column: 2; }
}

/* Radio choices for delivery and payment: the whole row is the target, the
   price sits at the end, and a hint can run under the label. */
/* A fieldset, so the group has a name for screen readers, with the browser's
   own box stripped. No margin shorthand: that would cancel the .stack gap
   that keeps it off the card heading. */
.choices { border: 0; padding: 0; margin-inline: 0; min-width: 0; display: grid; gap: var(--space-2); }
.choices + .error { margin-top: var(--space-2); }
.choice {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: var(--space-3);
  align-items: start;
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  cursor: pointer;
  transition: border-color var(--duration) var(--ease);
}
.choice:hover { border-color: var(--border-strong); }
.choice:has(input:checked) { border-color: var(--accent); background: var(--accent-soft); }
.choice input { margin: 0.2rem 0 0; accent-color: var(--accent); }
.choice__body { display: grid; gap: 0.125rem; }
.choice__label { font-size: var(--text-sm); }
.choice__hint { font-size: var(--text-xs); color: var(--text-subtle); }
.choice__price { font-size: var(--text-sm); font-variant-numeric: tabular-nums; white-space: nowrap; }

/* Sections the delivery choice makes irrelevant are hidden by app.js; without
   it everything shows and the server sorts it out. */
[data-address-fields][hidden], [data-pickup-fields][hidden], [data-free-note][hidden] { display: none; }

/* --------------------------------------------------------------------------
   Rich text editor (admin)
   -------------------------------------------------------------------------- */
.editor {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-raised);
  overflow: hidden;
}

.editor:focus-within { border-color: var(--border-strong); }

.editor__bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-2);
  border-bottom: 1px solid var(--border);
  background: var(--bg-sunken);
}

.editor__group { display: flex; gap: 2px; }
.editor__group + .editor__group {
  margin-left: var(--space-2);
  padding-left: var(--space-2);
  border-left: 1px solid var(--border);
}

.editor__btn {
  min-width: 2rem;
  height: 2rem;
  padding: 0 var(--space-2);
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text-muted);
  font-size: var(--text-sm);
  line-height: 1;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background var(--duration) var(--ease), color var(--duration) var(--ease);
}

.editor__btn:hover { background: var(--bg); color: var(--text); }
.editor__btn.is-active {
  background: var(--accent-soft);
  border-color: var(--accent);
  color: var(--accent-hover);
}
.editor__btn svg { width: 17px; height: 17px; }
.editor__btn.is-bold { font-weight: 700; }
.editor__btn.is-italic { font-style: italic; font-family: var(--font-display); }
.editor__btn.is-underline { text-decoration: underline; }

/* The writing area reads like the page it will become: the same prose
   rhythm, so what she sees is what the visitor gets. */
.editor__area {
  min-height: 18rem;
  max-height: 34rem;
  overflow-y: auto;
  padding: var(--space-4) var(--space-5);
  font-size: var(--text-sm);
  outline: none;
}

.editor__area:focus { outline: none; }
.editor__area > :first-child { margin-top: 0; }
.editor__area > :last-child { margin-bottom: 0; }
.editor__area h2 { font-size: var(--text-xl); }
.editor__area h3 { font-size: var(--text-lg); }
.editor__area a { color: var(--accent); }

/* The source textarea is hidden by JavaScript, not by CSS: without a script
   it stays and the form still works. */
.editor__source[hidden] { display: none; }
