/* =========================================================================
   Board — lístečky, zásobník, kontexty, slovník, agregáty, context map
   ========================================================================= */

/* =========================================================================
   Lísteček
   ========================================================================= */
/* Lísteček je papír, ne dlaždice.
   Event Storming má hotový vizuální jazyk, který nikdo jiný nemá: sytý
   barevný papír s tmavým písmem. Barva namíchaná na 12 % do tmavého panelu
   z něj dělá řádek v dashboardu. Tady je barva plocha a text je na ní tisk —
   proto je lísteček jediná světlá věc na desce a je vidět přes celý stůl.
   Rohy nezaobluje: papír se stříhá, ne frézuje. */
.sticky {
  --type-color: var(--fg-dim);
  --paper: color-mix(in srgb, var(--type-color) 74%, var(--paper-cream));
  --paper-edge: color-mix(in srgb, var(--type-color) 62%, var(--paper-shade));
  /* Tisk popisku typu. Musí být z barvy papíru, ale dost tmavý na to, aby
     desetibodové verzálky prošly na AA — samotná hrana papíru dá jen 2,6:1. */
  --paper-label: color-mix(in srgb, var(--paper-edge) 40%, #000);

  position: relative;
  display: flex;
  flex-direction: column;
  gap: 3px;
  width: var(--sticky-w);
  padding: var(--s3);
  border-radius: var(--radius-paper);
  background: var(--paper);
  color: var(--paper-ink-2);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .38),
    inset 0 0 0 1px color-mix(in srgb, var(--paper-edge) 42%, transparent),
    var(--shadow-paper);
  user-select: none;
  touch-action: none;
  transition: transform var(--dur) var(--ease),
              box-shadow var(--dur) var(--ease),
              opacity var(--dur) var(--ease);
  transform: translate(var(--drag-x, 0), var(--drag-y, 0)) rotate(var(--tilt, 0deg));
}

.sticky--event     { --type-color: var(--sticky-event); }
.sticky--command   { --type-color: var(--sticky-command); }
.sticky--policy    { --type-color: var(--sticky-policy); }
.sticky--hotspot   { --type-color: var(--sticky-hotspot); }
.sticky--readmodel { --type-color: var(--sticky-readmodel); }
.sticky--actor     { --type-color: var(--sticky-actor); }

/* Tvar rohu odlišuje typ i bez barvy. */
.sticky--event     { border-top-right-radius: 0; clip-path: polygon(0 0, calc(100% - 11px) 0, 100% 11px, 100% 100%, 0 100%); }
.sticky--policy    { border-top-left-radius: 0;  clip-path: polygon(11px 0, 100% 0, 100% 100%, 0 100%, 0 11px); }
.sticky--readmodel { box-shadow: inset 0 0 0 2px var(--paper), inset 0 0 0 3px color-mix(in srgb, var(--paper-edge) 55%, transparent), var(--shadow-paper); }
.sticky--readmodel::after {
  content: '';
  position: absolute;
  inset: 5px;
  border: 1px dashed color-mix(in srgb, var(--paper-edge) 60%, transparent);
  pointer-events: none;
}
.sticky--hotspot   { clip-path: polygon(0 0, 100% 0, 100% calc(100% - 7px), calc(100% - 8px) 100%, 8px 100%, 0 calc(100% - 7px)); }

.sticky.is-draggable { cursor: grab; }

/* Nikdo nelepí lístečky rovně. Náklon je deterministický podle pozice, takže
   se při překreslení nemění a nešumí — jen zruší dojem vysázené mřížky. */
.sticky:nth-child(4n+1) { --tilt: -0.5deg; }
.sticky:nth-child(4n+2) { --tilt:  0.4deg; }
.sticky:nth-child(4n+3) { --tilt: -0.25deg; }
.sticky:nth-child(4n+4) { --tilt:  0.65deg; }

@media (prefers-reduced-motion: reduce) {
  .sticky { --tilt: 0deg; }
}

.sticky-type {
  display: flex;
  align-items: center;
  gap: 5px;
  font-family: var(--font-display);
  font-size: 10px;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--paper-label);
}
.sticky-icon {
  display: inline-grid;
  place-items: center;
  width: 11px;
  font-size: 10px;
  line-height: 1;
  opacity: .8;
}

.sticky-label {
  font-size: var(--t-small);
  font-weight: 600;
  line-height: 1.28;
  color: var(--paper-ink);
}

.sticky--compact { width: auto; padding: var(--s2) var(--s3); gap: 2px; }
.sticky--compact .sticky-label { font-size: var(--t-micro); }
.sticky--compact .sticky-type-label { display: none; }

.sticky:hover:not(.is-dragging) {
  transform: translate(var(--drag-x, 0), var(--drag-y, 0)) rotate(var(--tilt, 0deg)) translateY(-3px);
  box-shadow:
    inset 0 0 0 1px color-mix(in srgb, var(--paper-edge) 62%, transparent),
    var(--shadow-lift);
}

.sticky.is-selected {
  box-shadow:
    0 0 0 2px var(--bg-0),
    0 0 0 4px var(--fg),
    var(--shadow-lift);
}

/* Tažený lísteček žije po dobu tažení v <body>, aby ho neořízl scrollující
   zásobník ani nepřekryly bloky pod ním. Pozici drží zapamatovaná --lift-*. */
.sticky.is-dragging {
  position: fixed;
  left: var(--lift-x, 0);
  top: var(--lift-y, 0);
  width: var(--lift-w, var(--sticky-w));
  margin: 0;
  z-index: 300;
  cursor: grabbing;
  pointer-events: none;
  transform: translate(var(--drag-x, 0), var(--drag-y, 0)) rotate(2.5deg) scale(1.04);
  box-shadow:
    inset 0 0 0 1px color-mix(in srgb, var(--paper-edge) 62%, transparent),
    0 10px 18px rgba(0, 0, 0, .55),
    0 32px 60px rgba(0, 0, 0, .5);
  transition: none;
}

.sticky-remove {
  position: absolute;
  top: 4px; right: 4px;
  width: 20px; height: 20px;
  display: grid;
  place-items: center;
  border-radius: 5px;
  font-size: 10px;
  color: var(--paper-label);
  opacity: 0;
  transition: opacity var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.sticky:hover .sticky-remove,
.sticky:focus-within .sticky-remove { opacity: 1; }
.sticky-remove:hover { color: var(--paper-cream); background: var(--paper-strike); }

/* --- Odznak typu (legenda, nabídky) --------------------------------------- */
.type-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 9px;
  border-radius: 99px;
  font-family: var(--font-mono);
  font-size: var(--t-micro);
  letter-spacing: .06em;
  text-transform: uppercase;
  background: color-mix(in oklab, var(--badge-color, var(--fg-dim)) 16%, var(--bg-2));
  color: color-mix(in oklab, var(--badge-color, var(--fg-dim)) 80%, var(--fg));
  box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--badge-color, var(--fg-dim)) 30%, transparent);
}
.type-badge-icon { display: inline-grid; place-items: center; width: 11px; line-height: 1; }

.type-badge--event     { --badge-color: var(--sticky-event); }
.type-badge--command   { --badge-color: var(--sticky-command); }
.type-badge--policy    { --badge-color: var(--sticky-policy); }
.type-badge--hotspot   { --badge-color: var(--sticky-hotspot); }
.type-badge--readmodel { --badge-color: var(--sticky-readmodel); }
.type-badge--actor     { --badge-color: var(--sticky-actor); }

/* =========================================================================
   Cílové zóny
   ========================================================================= */
[data-drop-target] {
  position: relative;
  transition: box-shadow var(--dur) var(--ease), background var(--dur) var(--ease);
}

[data-drop-target].is-awaiting-drop {
  box-shadow: inset 0 0 0 1px var(--line-accent);
}
[data-drop-target].is-dropzone-active {
  background: var(--accent-tint);
  box-shadow: inset 0 0 0 2px var(--accent);
}
[data-drop-target].just-received {
  animation: received var(--dur-slow) var(--ease-out);
}
@keyframes received {
  0%   { box-shadow: inset 0 0 0 2px var(--accent); }
  100% { box-shadow: inset 0 0 0 1px var(--line); }
}

.dropzone-action {
  display: none;
  margin-top: var(--s2);
  padding: 6px 12px;
  width: 100%;
  border-radius: var(--radius-sm);
  border: 1px dashed var(--line-accent);
  font-family: var(--font-display);
  font-size: var(--t-micro);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--accent);
  background: var(--accent-tint);
  transition: background var(--dur-fast) var(--ease);
}
.is-selecting [data-drop-target] > .dropzone-action { display: block; }
.dropzone-action:hover { background: color-mix(in oklab, var(--accent) 22%, transparent); }

/* Během tažení nesmí obsah zón krást pointer události. */
.is-dragging-any [data-drop-target] > * { pointer-events: none; }
.is-dragging-any .sticky.is-dragging { pointer-events: none; }

/* =========================================================================
   Fáze 2 — layout návrhu
   ========================================================================= */
.design {
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
  /* Bez explicitního minmax(0, …) roste sloupec do šířky nejširšího řádku —
     kroková lišta pak na mobilu roztáhne celou desku mimo obrazovku. */
  grid-template-columns: minmax(0, 1fr);
  height: 100%;
  min-height: 0;
}

/* --- Kroková lišta -------------------------------------------------------- */
.steps {
  display: flex;
  align-items: center;
  gap: var(--s5);
  padding: var(--s3) var(--s6);
  border-bottom: 1px solid var(--line);
  background: var(--bg-1);
}

/* min-width: 0 je nutné, aby se `overflow-x: auto` na užším displeji vůbec
   projevilo. Bez něj flex položka roste do šířky obsahu a roztáhne celou desku. */
.steps-list { display: flex; align-items: center; gap: var(--s2); min-width: 0; }

.step {
  display: flex;
  align-items: center;
  gap: var(--s2);
  padding: 7px 14px 7px 8px;
  border-radius: 99px;
  color: var(--fg-dim);
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.step:hover:not(:disabled) { background: var(--bg-2); color: var(--fg); }

.step-num {
  display: grid;
  place-items: center;
  width: 22px; height: 22px;
  border-radius: 50%;
  background: var(--bg-3);
  font-size: var(--t-micro);
  font-weight: 700;
  color: var(--fg-dim);
}
.step-label { font-size: var(--t-small); font-weight: 500; }

.step.is-active { background: var(--accent-tint); color: var(--fg); }
.step.is-active .step-num { background: var(--accent); color: var(--accent-ink); }
.step.is-done .step-num { background: var(--ok-tint); color: var(--ok); }
.step.is-locked { opacity: .4; cursor: not-allowed; }

.steps-hint { font-size: var(--t-small); color: var(--fg-dim); }

/* --- Plocha kroku --------------------------------------------------------- */
.design-stage { min-height: 0; min-width: 0; overflow: hidden; }

/* --- Patička -------------------------------------------------------------- */
.design-foot {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--s4);
  padding: var(--s3) var(--s6);
  border-top: 1px solid var(--line);
  background: var(--bg-1);
}
.design-foot-note { font-size: var(--t-small); color: var(--warn); text-align: center; }

/* =========================================================================
   Krok 2a — zásobník a kontexty
   ========================================================================= */
.board {
  display: grid;
  grid-template-rows: auto minmax(0, 1fr);
  height: 100%;
  min-height: 0;
}

.rack {
  display: flex;
  flex-direction: column;
  gap: var(--s3);
  padding: var(--s4) var(--s6);
  border-bottom: 1px solid var(--line);
  background: color-mix(in oklab, var(--bg-inset) 70%, var(--bg-0));
  max-height: 38vh;
}
.rack-head { display: flex; align-items: baseline; gap: var(--s2); }
.rack-count {
  padding: 1px 8px;
  border-radius: 99px;
  background: var(--bg-3);
  font-size: var(--t-micro);
  color: var(--fg-dim);
}
.rack-items {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
  overflow: auto;
  padding-bottom: var(--s1);
  min-height: 76px;
}
/* Lísteček uříznutý spodní hranou vypadá jako chyba vykreslení. Fade z něj
   udělá to, čím je: papír, který pokračuje pod okrajem. Zapíná ho až
   renderRack(), když se obsah opravdu nevejde. */
.rack-items.is-overflowing {
  mask-image: linear-gradient(to bottom, #000 calc(100% - 28px), transparent 100%);
}
.rack-empty { font-size: var(--t-small); color: var(--ok); align-self: center; }

.contexts {
  display: flex;
  flex-direction: column;
  gap: var(--s4);
  min-height: 0;
  overflow: auto;
  padding: var(--s5) var(--s6) var(--s6);
}
.contexts-empty {
  max-width: 52ch;
  font-size: var(--t-small);
  color: var(--fg-faint);
  line-height: var(--lh-body);
}
.contexts-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: var(--s4);
  align-items: start;
}

.context-zone {
  --ctx-color: var(--accent);
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--s3);
  padding: var(--s4);
  border-radius: var(--radius-lg);
  background: color-mix(in oklab, var(--ctx-color) 9%, var(--bg-1));
  box-shadow:
    inset 0 0 0 1px color-mix(in oklab, var(--ctx-color) 42%, transparent),
    0 0 30px color-mix(in oklab, var(--ctx-color) 10%, transparent);
  min-height: 168px;
  overflow: hidden;
}
/* Barevná hrana nahoře — kontexty se musí rozeznat na první pohled. */
.context-zone::before {
  content: '';
  position: absolute;
  inset: 0 0 auto 0;
  height: 3px;
  background: linear-gradient(90deg, var(--ctx-color), color-mix(in oklab, var(--ctx-color) 25%, transparent));
}

.context-head { display: flex; align-items: center; gap: var(--s2); }
.context-head::before {
  content: '';
  flex: none;
  width: 9px; height: 9px;
  border-radius: 50%;
  background: var(--ctx-color);
  box-shadow: 0 0 10px var(--ctx-color);
}
.context-name {
  flex: 1;
  min-width: 0;
  padding: 5px 8px;
  border-radius: var(--radius-sm);
  background: transparent;
  font-size: var(--t-h3);
  font-weight: 600;
  color: var(--fg);
  box-shadow: inset 0 0 0 1px transparent;
  transition: box-shadow var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.context-name::placeholder { color: var(--fg-faint); font-weight: 400; }
.context-name:hover { background: var(--bg-2); }
.context-name:focus { background: var(--bg-2); box-shadow: inset 0 0 0 1px var(--line-accent); }

.context-count {
  padding: 2px 8px;
  border-radius: 99px;
  background: color-mix(in oklab, var(--ctx-color) 22%, transparent);
  color: var(--fg);
  font-size: var(--t-micro);
  font-weight: 700;
}
.context-delete {
  width: 26px; height: 26px;
  display: grid; place-items: center;
  border-radius: var(--radius-sm);
  font-size: 11px;
  color: var(--fg-faint);
  opacity: 0;
  transition: opacity var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.context-zone:hover .context-delete,
.context-zone:focus-within .context-delete { opacity: 1; }
.context-delete:hover { color: var(--danger); background: var(--danger-tint); }

.context-items { display: flex; flex-wrap: wrap; gap: var(--s2); flex: 1; align-content: flex-start; }
.context-empty {
  width: 100%;
  padding: var(--s4) var(--s3);
  border-radius: var(--radius);
  border: 1px dashed var(--line-strong);
  text-align: center;
  font-size: var(--t-small);
  color: var(--fg-faint);
}

.context-warning {
  display: flex;
  gap: var(--s2);
  padding: var(--s2) var(--s3);
  border-radius: var(--radius-sm);
  background: var(--warn-tint);
  font-size: var(--t-micro);
  line-height: var(--lh-snug);
  color: var(--warn);
}
.context-warning::before { content: '!'; font-weight: 700; }

.context-add {
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  align-self: flex-start;
  padding: var(--s3) var(--s5);
  border-radius: var(--radius);
  border: 1px dashed var(--line-strong);
  font-size: var(--t-small);
  font-weight: 500;
  color: var(--fg-dim);
  transition: color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.context-add:hover { color: var(--accent); border-color: var(--line-accent); background: var(--accent-tint); }
.context-add-icon { font-size: 15px; line-height: 1; }

@media (max-width: 1023px) {
  .steps { flex-direction: column; align-items: stretch; gap: var(--s2); padding: var(--s3) var(--s4); min-width: 0; }
  .steps-list { width: 100%; overflow-x: auto; flex-wrap: nowrap; }
  .steps-list > li { flex: 0 0 auto; }
  .contexts, .rack { padding-inline: var(--s4); }
  .contexts-grid { grid-template-columns: 1fr; }
  .design-foot { padding-inline: var(--s4); }
}

/* =========================================================================
   Krok 2b — Ubiquitous Language
   ========================================================================= */
.glossary {
  display: grid;
  grid-template-rows: auto minmax(0, 1fr);
  height: 100%;
  min-height: 0;
}

.attr-pool {
  display: flex;
  flex-direction: column;
  gap: var(--s2);
  padding: var(--s4) var(--s6);
  border-bottom: 1px solid var(--line);
  background: color-mix(in oklab, var(--bg-inset) 70%, var(--bg-0));
}
.attr-pool-hint { font-size: var(--t-small); color: var(--fg-dim); }
.attr-pool-items {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
  margin-top: var(--s2);
  min-height: 40px;
}

.attribute {
  --attr-color: var(--fg-dim);
  /* Barva, kterou se atribut kreslí. V zásobníku je neutrální, v buňce
     přebírá barvu jazyka — jedna proměnná, aby se plocha, rámeček i tečka
     nemohly rozejít. Dřív brala plocha i rámeček `--attr-color` napřímo,
     takže i po ztlumení tečky zůstal jazyk čitelný z okraje. */
  --attr-ink: var(--fg-faint);
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 13px;
  border-radius: 99px;
  background: color-mix(in oklab, var(--attr-ink) 15%, var(--bg-2));
  box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--attr-ink) 34%, transparent);
  font-size: var(--t-small);
  color: var(--fg);
  user-select: none;
  touch-action: none;
  transform: translate(var(--drag-x, 0), var(--drag-y, 0));
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
/* Jazyk je nesený barvou i tvarem tečky před názvem — ale AŽ POTOM, co
   atribut někam přiřadím.

   V zásobníku byly atributy obarvené podle `language`, tedy podle skryté osy,
   kterou má hráč teprve objevit. Dvanáct atributů tam leželo ve třech
   zřetelných barevných skupinách po čtyřech, navíc v pořadí odpovídajícím
   kontextům, takže otázka „kdo tenhle údaj doopravdy potřebuje?" se dala
   vyřešit tříděním podle barvy, aniž by hráč uvažoval o doméně.

   Nepřiřazený atribut je proto papír bez barvy. Jakmile leží v buňce,
   barva i tvar se rozsvítí a začnou dělat svou skutečnou práci: ukazovat,
   že v jedné buňce leží tři různé světy, tedy God Entity. */
.attribute.is-placed { --attr-ink: var(--attr-color); }
.attribute::before {
  content: '';
  width: 7px; height: 7px;
  margin-right: 8px;
  border-radius: 50%;
  background: var(--attr-ink);
}
.attribute--time  { --attr-color: var(--ctx-0); }
.attribute--care  { --attr-color: var(--sticky-readmodel); }
.attribute--money { --attr-color: var(--sticky-actor); }
.attribute.is-placed.attribute--time::before  { border-radius: 50%; }
.attribute.is-placed.attribute--care::before  { border-radius: 2px; }
.attribute.is-placed.attribute--money::before { border-radius: 0; clip-path: polygon(50% 0, 100% 100%, 0 100%); }

.attribute.is-draggable { cursor: grab; }
/* Hover nesmí prozradit jazyk dřív než tečka. `--attr-color` je na prvku
   nastavená pořád (pro chvíli, kdy atribut někam přistane), takže se tady
   musí ptát na `is-placed`, ne na proměnnou. */
.attribute:hover { box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--attr-ink) 60%, transparent); }
.attribute.is-selected { box-shadow: 0 0 0 2px var(--accent); }
.attribute.is-dragging {
  position: fixed;
  left: var(--lift-x, 0);
  top: var(--lift-y, 0);
  width: var(--lift-w, auto);
  margin: 0;
  z-index: 300;
  pointer-events: none;
  transform: translate(var(--drag-x, 0), var(--drag-y, 0)) scale(1.06);
  transition: none;
}

.attribute-remove {
  margin-left: var(--s2);
  margin-right: -4px;
  width: 16px; height: 16px;
  display: grid; place-items: center;
  border-radius: 50%;
  font-size: 9px;
  color: var(--fg-dim);
}
.attribute-remove:hover { color: var(--danger); background: var(--danger-tint); }

/* --- Termíny -------------------------------------------------------------- */
.terms {
  display: flex;
  flex-direction: column;
  gap: var(--s5);
  min-height: 0;
  overflow: auto;
  padding: var(--s5) var(--s6) var(--s7);
}

.term-card {
  padding: var(--s4);
  border-radius: var(--radius-lg);
  background: var(--bg-1);
  box-shadow: inset 0 0 0 1px var(--line);
}
.term-head { display: flex; align-items: baseline; gap: var(--s3); margin-bottom: var(--s4); }
.term-name { font-size: var(--t-h3); font-weight: 600; }
.term-note { font-size: var(--t-micro); color: var(--fg-faint); }

.term-cells {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: var(--s3);
  align-items: start;
}

.term-cell {
  --ctx-color: var(--accent);
  display: flex;
  flex-direction: column;
  gap: var(--s3);
  padding: var(--s3);
  border-radius: var(--radius);
  background: color-mix(in oklab, var(--ctx-color) 7%, var(--bg-2));
  box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--ctx-color) 30%, transparent);
  min-height: 128px;
}
.term-cell.is-god-entity {
  background: var(--danger-tint);
  box-shadow: inset 0 0 0 1px var(--danger);
}

.term-cell-context {
  display: flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-display);
  font-size: var(--t-micro);
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--ctx-color);
}
.term-cell-context::before {
  content: '';
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--ctx-color);
}
.term-cell.is-god-entity .term-cell-context { color: var(--danger); }
.term-cell.is-god-entity .term-cell-context::before { background: var(--danger); }

.term-cell-attrs { display: flex; flex-wrap: wrap; gap: 6px; flex: 1; align-content: flex-start; }
.term-cell-empty { font-size: var(--t-micro); color: var(--fg-faint); line-height: var(--lh-snug); }

.term-cell-naming { display: block; }
.term-cell-input {
  width: 100%;
  padding: 7px 10px;
  border-radius: var(--radius-sm);
  background: var(--bg-inset);
  box-shadow: inset 0 0 0 1px var(--line-strong);
  font-family: var(--font-mono);
  font-size: var(--t-small);
  color: var(--accent);
  transition: box-shadow var(--dur-fast) var(--ease);
}
.term-cell-input::placeholder { font-family: var(--font-sans); color: var(--fg-faint); }
.term-cell-input:focus { box-shadow: inset 0 0 0 1px var(--accent); }

@media (max-width: 1023px) {
  .attr-pool, .terms { padding-inline: var(--s4); }
  .term-cells { grid-template-columns: 1fr; }
}

/* =========================================================================
   Krok 2c — Agregáty a invarianty
   ========================================================================= */
.aggregates {
  display: grid;
  /* Čtyři pásy: úvod, přehled pravidel, procesy přes hranici a teprve pak
     mřížka kontextů, která si bere zbytek výšky a scrolluje. Dokud tu byly
     řádky dva, zmáčkly se oba nové bloky do zbytku prvního — přehled
     pravidel měl 32 px místo plné výšky a fakticky nebyl vidět. */
  grid-template-rows: auto auto auto minmax(0, 1fr);
  height: 100%;
  min-height: 0;
}

.aggregates-intro {
  padding: var(--s4) var(--s6);
  border-bottom: 1px solid var(--line);
  background: color-mix(in oklab, var(--bg-inset) 70%, var(--bg-0));
}
.aggregates-intro .hint { max-width: 110ch; }

.aggregates-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: var(--s4);
  align-items: start;
  min-height: 0;
  overflow: auto;
  padding: var(--s5) var(--s6) var(--s7);
}

.agg-column {
  --ctx-color: var(--accent);
  display: flex;
  flex-direction: column;
  gap: var(--s3);
}
.agg-column-head { display: flex; align-items: center; gap: var(--s3); }
.agg-column-name {
  display: flex;
  align-items: center;
  gap: var(--s2);
  flex: 1;
  min-width: 0;
  font-size: var(--t-h3);
  font-weight: 600;
}
.agg-column-name::before {
  content: '';
  flex: none;
  width: 9px; height: 9px;
  border-radius: 50%;
  background: var(--ctx-color);
  box-shadow: 0 0 10px var(--ctx-color);
}

.agg-add {
  padding: 5px 11px;
  border-radius: var(--radius-sm);
  border: 1px dashed var(--line-strong);
  font-size: var(--t-micro);
  color: var(--fg-dim);
  white-space: nowrap;
  transition: color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.agg-add:hover { color: var(--ctx-color); border-color: var(--ctx-color); }

.agg-pool {
  padding: var(--s3);
  border-radius: var(--radius);
  background: var(--bg-inset);
  box-shadow: inset 0 0 0 1px var(--line);
}
.agg-pool-title { margin-bottom: var(--s2); }
.agg-pool-items { display: flex; flex-wrap: wrap; gap: 6px; min-height: 30px; }
.agg-pool-empty { font-size: var(--t-micro); color: var(--ok); }

.agg-list { display: flex; flex-direction: column; gap: var(--s3); }
.agg-empty {
  padding: var(--s4);
  border-radius: var(--radius);
  border: 1px dashed var(--line-strong);
  font-size: var(--t-small);
  color: var(--fg-faint);
  line-height: var(--lh-snug);
}

.agg-card {
  display: flex;
  flex-direction: column;
  gap: var(--s3);
  padding: var(--s3);
  border-radius: var(--radius);
  background: color-mix(in oklab, var(--ctx-color) 8%, var(--bg-1));
  box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--ctx-color) 34%, transparent);
}

.agg-head { display: flex; align-items: center; gap: var(--s2); }
.agg-badge {
  flex: none;
  padding: 3px 7px;
  border-radius: 4px;
  background: var(--ctx-color);
  color: var(--bg-0);
  font-family: var(--font-mono);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .1em;
}
.agg-name {
  flex: 1;
  min-width: 0;
  padding: 5px 8px;
  border-radius: var(--radius-sm);
  background: transparent;
  font-size: var(--t-small);
  font-weight: 500;
  color: var(--fg);
  transition: background var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}
.agg-name::placeholder { font-family: var(--font-sans); color: var(--fg-faint); font-weight: 400; }
.agg-name:hover { background: var(--bg-2); }
.agg-name:focus { background: var(--bg-2); box-shadow: inset 0 0 0 1px var(--ctx-color); }

.agg-delete {
  width: 24px; height: 24px;
  display: grid; place-items: center;
  border-radius: var(--radius-sm);
  font-size: 10px;
  color: var(--paper-label);
  opacity: 0;
  transition: opacity var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.agg-card:hover .agg-delete, .agg-card:focus-within .agg-delete { opacity: 1; }
.agg-delete:hover { color: var(--danger); background: var(--danger-tint); }

.agg-items { display: flex; flex-wrap: wrap; gap: 6px; min-height: 34px; }
.agg-items-empty {
  width: 100%;
  padding: var(--s3);
  border-radius: var(--radius-sm);
  border: 1px dashed var(--line-strong);
  text-align: center;
  font-size: var(--t-micro);
  color: var(--fg-faint);
}

/* Značka Entity / Value Object na položeném atributu. Kosočtverec plný =
   má vlastní identitu, prázdný = jenom hodnota. Tvar, ne barva: osa jazyka
   už barvu obsadila a míchat dvě barevné škály na jednom lístečku by
   znamenalo, že se nedá číst ani jedna. */
.attribute-mark {
  flex: none;
  font-size: 9px;
  line-height: 1;
  opacity: .55;
}
.attribute-mark:empty { display: none; }
.attribute--entity .attribute-mark { opacity: .9; }

/* Přehled pravidel nad sloupci. Není to nabídka ani nápověda, kam co dát —
   je to seznam toho, co má návrh uhlídat, a kde ty dvě poloviny právě leží.
   Bez něj se hráč díval na tři sloupce lístečků a otázku „co musí platit
   vždycky", jejíž odpověď byla schovaná za tlačítkem, které ještě nezmáčkl. */
.agg-rules {
  margin: var(--s4) var(--s6) 0;
  padding: var(--s4);
  border-radius: var(--radius);
  background: var(--bg-1);
  box-shadow: inset 0 0 0 1px var(--line);
}
/* Pás, ne sloupec. Přehled je referenční informace — když si vzal 170 px
   výšky, odsunul vlastní pracovní plochu (sloupce s agregáty) pod okraj
   obrazovky. Čtyři pravidla se jako čipy vejdou na jednu až dvě řádky. */
.agg-rules-list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2) var(--s3);
  margin-top: var(--s2);
}
.agg-rule {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  padding: 4px var(--s3);
  border-radius: 99px;
  font-size: var(--t-micro);
  background: var(--bg-2);
  box-shadow: inset 0 0 0 1px var(--line);
  color: var(--fg-dim);
}
.agg-rule-mark { flex: none; color: var(--fg-faint); }
.agg-rule.is-guarded { box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--ok) 40%, transparent); }
.agg-rule.is-guarded .agg-rule-mark { color: var(--ok); }
.agg-rule.is-guarded .agg-rule-label { color: var(--fg); }
.agg-rule-label { line-height: var(--lh-snug); }
.agg-rule-where { flex: none; color: var(--fg-faint); }

/* Procesy přes hranici kontextu. Vizuálně oddělené od agregátů, protože je
   to jiný druh rozhodnutí: tady agregát nepomůže a hráč volí mezi eventuální
   konzistencí s rekonciliací a tím, že se na to vykašle. */
.agg-processes {
  margin: var(--s3) var(--s6) var(--s4);
  padding: var(--s3) var(--s4);
  border-radius: var(--radius);
  background: var(--bg-1);
  box-shadow: inset 0 0 0 1px var(--line);
}
.agg-processes-hint {
  margin: var(--s2) 0 0;
  font-size: var(--t-micro);
  line-height: var(--lh-snug);
  color: var(--fg-faint);
}
.agg-processes-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: var(--s4);
  margin-top: var(--s4);
}
.agg-process {
  padding: var(--s3) var(--s4);
  border-radius: var(--radius-sm);
  border-left: 2px solid var(--line-strong);
  background: var(--bg-2);
}
.agg-process.is-compensated { border-left-color: var(--ok); }
.agg-process.is-transactional { border-left-color: var(--warn); }
.agg-process-label { margin: 0; font-size: var(--t-small); font-weight: 600; color: var(--fg); }
.agg-process-explain {
  margin: var(--s2) 0 0;
  font-size: var(--t-micro);
  line-height: var(--lh-snug);
  color: var(--fg-dim);
}
.agg-process-where { margin: var(--s2) 0 0; font-size: var(--t-micro); color: var(--fg-faint); }
.agg-process-actions { margin-top: var(--s3); }
.agg-process-toggle {
  padding: 6px var(--s3);
  border-radius: 99px;
  font-size: var(--t-micro);
  color: var(--fg-dim);
  background: var(--bg-3);
  box-shadow: inset 0 0 0 1px var(--line);
}
.agg-process-toggle:hover { color: var(--fg); }
.agg-process-toggle.is-on {
  color: var(--ok);
  background: var(--ok-tint);
  box-shadow: inset 0 0 0 1px var(--ok);
}
.agg-process-state {
  margin: var(--s2) 0 0;
  font-size: var(--t-micro);
  line-height: var(--lh-snug);
  color: var(--fg-faint);
}

/* Zámek nad agregátem: kolik lístečků drží jedna transakce a co to stojí.
   Stojí to v hlavičce karty vedle jména kořenové entity, protože je to
   vlastnost té konzistenční hranice, ne poznámka pod čarou. */
.agg-lock {
  margin-left: auto;
  padding: 2px var(--s2);
  border-radius: var(--radius-sm);
  font-family: var(--font-mono);
  font-size: var(--t-micro);
  white-space: nowrap;
  color: var(--fg-faint);
  background: var(--bg-2);
}
.agg-lock.is-long { color: var(--warn); background: var(--warn-tint); }

/* Otázka nad přerostlým agregátem. Není to chyba a nesmí tak vypadat —
   proto varovná barva textu, ale bez rámečku a bez ikony chyby. */
.agg-oversized {
  width: 100%;
  margin-top: var(--s2);
  padding: var(--s2) var(--s3);
  border-left: 2px solid var(--warn);
  font-size: var(--t-micro);
  line-height: 1.5;
  color: var(--fg-dim);
}

.agg-invariants { padding-top: var(--s3); border-top: 1px dashed var(--line-strong); }
.agg-invariants-title { margin-bottom: var(--s2); }
.agg-invariants-list { display: flex; flex-direction: column; gap: 4px; }

.invariant-chip {
  display: flex;
  align-items: flex-start;
  gap: var(--s2);
  padding: 6px 9px;
  border-radius: var(--radius-sm);
  text-align: left;
  font-size: var(--t-micro);
  line-height: var(--lh-snug);
  color: var(--fg-dim);
  box-shadow: inset 0 0 0 1px var(--line);
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}
.invariant-chip:hover:not(:disabled) { background: var(--bg-2); color: var(--fg); }
.invariant-chip:disabled { opacity: .35; cursor: not-allowed; }
.invariant-chip-mark { flex: none; font-size: 10px; line-height: 1.4; color: var(--fg); }

.invariant-chip.is-pinned {
  background: color-mix(in oklab, var(--sticky-policy) 16%, transparent);
  color: var(--fg);
  box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--sticky-policy) 55%, transparent);
}
/* Připnutý stav nese i podbarvení a rámeček, takže značka smí být světlejší
   než čistá fialová — ta na vlastním tintu dá jen 4,5:1 těsně pod hranu. */
.invariant-chip.is-pinned .invariant-chip-mark {
  color: color-mix(in oklab, var(--sticky-policy) 68%, #FFF);
}

@media (max-width: 1023px) {
  .aggregates-intro, .aggregates-grid { padding-inline: var(--s4); }
  .agg-rules, .agg-processes { margin-inline: var(--s4); }
  .aggregates-grid { grid-template-columns: 1fr; }
}

/* =========================================================================
   Krok 2d — Context Map
   ========================================================================= */
.ctxmap {
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
  height: 100%;
  min-height: 0;
}

.ctxmap-intro {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--s4);
  padding: var(--s4) var(--s6);
  border-bottom: 1px solid var(--line);
  background: color-mix(in oklab, var(--bg-inset) 70%, var(--bg-0));
}
.ctxmap-legend { display: flex; flex-wrap: wrap; row-gap: var(--s2); gap: var(--s4); }
.legend-item {
  display: flex;
  align-items: center;
  gap: var(--s2);
  font-size: var(--t-micro);
  color: var(--fg-dim);
  white-space: nowrap;
}
.legend-line { width: 26px; height: 2px; border-radius: 2px; }
.legend-item--event .legend-line {
  background: repeating-linear-gradient(90deg, var(--fg-faint) 0 5px, transparent 5px 9px);
}
.legend-item--sync .legend-line { background: var(--warn); height: 3px; }
.legend-mark { font-family: var(--font-mono); font-weight: 600; gap: var(--s1); }
.legend-mark-text { font-family: var(--font-sans); font-weight: 400; color: var(--fg-dim); }

.ctxmap-canvas {
  position: relative;
  min-height: 0;
  overflow: hidden;
  background: var(--bg-inset);
}
.ctxmap-canvas.is-linking { cursor: crosshair; }

/* -------------------------------------------------------------------------
   Seznam hranic — druhá, rovnocenná cesta k témuž panelu.
   Plátno je pro myš; tohle je pro klávesnici a pro čtečku. Proto to není
   schované za `visually-hidden`: vidět má být obojí.
   ------------------------------------------------------------------------- */
.ctxmap-edges {
  padding: var(--s3) var(--s6) var(--s4);
  border-top: 1px solid var(--line);
  background: color-mix(in oklab, var(--bg-inset) 70%, var(--bg-0));
}
.ctxmap-edges-title { margin: 0 0 var(--s2); }
.ctxmap-edge-list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
  margin: 0;
  padding: 0;
  list-style: none;
}
.ctxmap-edge-empty {
  margin: 0;
  font-size: var(--t-micro);
  color: var(--fg-faint);
}
.ctxmap-edge {
  display: flex;
  align-items: baseline;
  gap: var(--s2);
  padding: var(--s2) var(--s3);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: var(--bg-2);
  color: var(--fg);
  font: inherit;
  font-size: var(--t-small);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.ctxmap-edge:hover { background: var(--bg-3); border-color: var(--line-accent); }
/* Druh spoje se nese tvarem levé hrany, ne barvou — stejně jako na plátně. */
.ctxmap-edge--sync { border-left-width: 3px; border-left-color: var(--warn); }
.ctxmap-edge--event { border-left-width: 3px; border-left-style: dashed; }
.ctxmap-edge-rel { font-weight: 600; font-size: var(--t-micro); color: var(--fg); }
.ctxmap-edge-payload { font-size: var(--t-micro); color: var(--fg-dim); }

/* Vztah je vlastnost hranice: u druhého toku se nevolí, jen se ukáže. */
.link-boundary-note {
  margin: 0 0 var(--s3);
  padding: var(--s2) var(--s3);
  border-left: 2px solid var(--line-accent);
  font-size: var(--t-micro);
  line-height: var(--lh-snug);
  color: var(--fg-dim);
  background: var(--bg-2);
}
.link-rel.is-locked { opacity: .45; cursor: default; }
.link-rel.is-locked.is-chosen { opacity: 1; }

.ctxmap-svg { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.ctxmap-svg .ctx-link-hit { pointer-events: stroke; }

/* Doménová událost je tenká přerušovaná čára: hranice, přes kterou něco
   proteče a nikdo na nic nečeká. Synchronní volání je plná a tlustá —
   je vidět, že tudy vede závislost, na které se dá zaseknout. */
.ctx-link path:first-child { fill: none; stroke-width: 1.5; }
.ctx-link--event path:first-child {
  stroke: var(--fg-faint);
  stroke-dasharray: 7 6;
  animation: flow 1.4s linear infinite;
}
.ctx-link--sync path:first-child { stroke: var(--warn); stroke-width: 3; }
@keyframes flow { to { stroke-dashoffset: -26; } }

.ctx-link-hit { fill: none; stroke: transparent; stroke-width: 22; cursor: pointer; }
.ctx-link:hover path:first-child { stroke: var(--fg); stroke-width: 2.5; }
.ctx-link--sync:hover path:first-child { stroke: var(--warn); stroke-width: 4; }

/* Štítek spoje: vzor vztahu a payload v jedné destičce, posazené na čáru.
   Dva samostatné plovoucí texty se navzájem trefovaly a nebylo poznat,
   ke které hraně patří. */
.ctx-link-badge { pointer-events: none; }
.ctx-link-plate { fill: var(--bg-inset); stroke: var(--line); stroke-width: 1; }
.ctx-link-mark {
  font-family: var(--font-mono);
  font-size: var(--t-micro);
  font-weight: 600;
  fill: var(--fg);
  letter-spacing: .04em;
}
.ctx-link-sep { font-size: 10px; fill: var(--fg-faint); }
.ctx-link-payload { font-family: var(--font-mono); font-size: 10px; fill: var(--fg-dim); }

.ctx-link--rel-shared-kernel .ctx-link-mark { fill: var(--warn); }
.ctx-link--rel-shared-kernel .ctx-link-plate { stroke: color-mix(in srgb, var(--warn) 45%, transparent); }
.ctx-link--rel-acl .ctx-link-plate { stroke: var(--line-strong); }

.ctx-guide { fill: none; stroke: var(--accent); stroke-width: 2; stroke-dasharray: 5 5; opacity: .7; }

.ctxmap-nodes { position: absolute; inset: 0; }

.ctx-node {
  --ctx-color: var(--accent);
  position: absolute;
  left: var(--node-x, 50%);
  top: var(--node-y, 50%);
  transform: translate(-50%, -50%);
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 150px;
  padding: var(--s3) var(--s4);
  border-radius: var(--radius);
  background: var(--bg-1);
  border-top: 3px solid var(--ctx-color);
  box-shadow:
    inset 0 0 0 1px var(--line-strong),
    var(--shadow-card);
  cursor: grab;
  user-select: none;
  touch-action: none;
  text-align: center;
  transition: box-shadow var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.ctx-node:hover { background: var(--bg-2); box-shadow: inset 0 0 0 1px var(--ctx-color), var(--shadow-lift); }
.ctx-node.is-dragging { cursor: grabbing; z-index: 5; }
.ctx-node.is-selected,
.ctx-node.is-link-target {
  box-shadow: 0 0 0 2px var(--accent), var(--shadow-lift);
}

.ctx-node-name { font-size: var(--t-small); font-weight: 600; color: var(--fg); }
.ctx-node-count { font-size: var(--t-micro); color: var(--fg-dim); }

/* --- Panel volby typu spoje ----------------------------------------------- */
.link-group-title {
  margin: var(--s5) 0 var(--s2);
  font-family: var(--font-display);
  font-size: var(--t-micro);
  font-weight: 500;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--fg-dim);
}
.link-group-title:first-child { margin-top: 0; }
.link-group-hint { margin: 0 0 var(--s3); font-size: var(--t-micro); color: var(--fg-faint); }

.link-relationships { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s3); }

.link-rel {
  display: flex;
  flex-direction: column;
  gap: var(--s2);
  padding: var(--s3) var(--s4);
  border-radius: var(--radius);
  text-align: left;
  background: var(--bg-2);
  box-shadow: inset 0 0 0 1px var(--line);
  transition: box-shadow var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.link-rel:hover { background: var(--bg-3); }
.link-rel.is-chosen {
  background: color-mix(in oklab, var(--accent) 14%, var(--bg-2));
  box-shadow: inset 0 0 0 2px var(--accent);
}
.link-rel-title { font-size: var(--t-small); font-weight: 600; color: var(--fg); }
.link-rel-body { font-size: var(--t-micro); line-height: var(--lh-snug); color: var(--fg-dim); }

.link-relationships + [data-role="swap"] { margin-top: var(--s3); }

/* =========================================================================
   Dvě osy na hranici

   Open Host je rozhodnutí upstreamu, Conformist/ACL rozhodnutí downstreamu.
   Vizuálně to musí být dvě skupiny, ne jedna mřížka — jinak se hráč naučí
   přesně to, co ta přestavba měla odstranit: že jsou to body na jedné škále.
   ========================================================================= */
.link-axis { margin-top: var(--s4); }
.link-axis-title {
  margin: 0 0 var(--s2);
  font-family: var(--font-display);
  font-size: var(--t-micro);
  font-weight: 500;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--fg-dim);
}
.link-axis-note {
  margin: 0 0 var(--s3);
  padding: var(--s2) var(--s3);
  border-left: 2px solid var(--warn);
  font-size: var(--t-micro);
  line-height: var(--lh-snug);
  color: var(--fg-dim);
}
.link-axis-options { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s3); }

/* Sdílený kernel ruší obě osy — zešednou, ale zůstanou čitelné, aby bylo
   vidět, co se tou volbou vypnulo. */
.link-axis.is-muted { opacity: .4; }
.link-rel--wide { width: 100%; }
.link-rel[disabled] { cursor: default; }

.link-cost {
  margin: var(--s4) 0 0;
  padding-top: var(--s3);
  border-top: 1px solid var(--line);
  font-size: var(--t-micro);
  color: var(--fg-faint);
}

.link-options { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s3); margin: var(--s5) 0 var(--s4); }

.link-option {
  --opt-color: var(--fg-dim);
  display: flex;
  flex-direction: column;
  gap: var(--s2);
  padding: var(--s4);
  border-radius: var(--radius);
  text-align: left;
  background: var(--bg-2);
  box-shadow: inset 0 0 0 1px var(--line);
  transition: box-shadow var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.link-option:hover { background: var(--bg-3); }
.link-option--event { --opt-color: var(--accent); }
.link-option--sync  { --opt-color: var(--warn); }
.link-option.is-chosen {
  background: color-mix(in oklab, var(--opt-color) 14%, var(--bg-2));
  box-shadow: inset 0 0 0 2px var(--opt-color);
}

.link-option-head { display: flex; align-items: center; gap: var(--s2); }
.link-option-mark { width: 26px; height: 3px; border-radius: 2px; flex: none; }
.link-option--event .link-option-mark { background: repeating-linear-gradient(90deg, var(--accent) 0 5px, transparent 5px 9px); }
.link-option--sync .link-option-mark { background: var(--warn); }
.link-option-title { font-size: var(--t-small); font-weight: 600; color: var(--fg); }
.link-option-body { font-size: var(--t-micro); line-height: var(--lh-snug); color: var(--fg-dim); }

.link-payload { display: flex; flex-direction: column; gap: var(--s2); }
.link-payload-input {
  padding: 9px 12px;
  border-radius: var(--radius-sm);
  background: var(--bg-inset);
  box-shadow: inset 0 0 0 1px var(--line-strong);
  font-size: var(--t-small);
  color: var(--accent);
}
.link-payload-input::placeholder { font-family: var(--font-sans); color: var(--fg-faint); }
.link-payload-input:focus { box-shadow: inset 0 0 0 1px var(--accent); }

@media (max-width: 1023px) {
  .ctxmap-intro { padding-inline: var(--s4); }
  .link-options { grid-template-columns: 1fr; }
  .link-relationships { grid-template-columns: 1fr; }
  .ctx-node { min-width: 120px; padding: var(--s2) var(--s3); }
}

/* =========================================================================
   Fáze 4 — Change Request
   ========================================================================= */
.cr {
  display: flex;
  flex-direction: column;
  gap: var(--s5);
  height: 100%;
  min-height: 0;
  overflow: auto;
  padding: var(--s6) max(var(--s6), calc((100% - 1100px) / 2)) var(--s7);
}

.cr-message {
  padding: var(--s5);
  border-radius: var(--radius-lg);
  background: var(--bg-1);
  box-shadow: inset 0 0 0 1px var(--line-strong), var(--shadow-card);
}
.cr-from { display: flex; align-items: center; gap: var(--s3); margin-bottom: var(--s4); }
.cr-avatar {
  display: grid; place-items: center;
  width: 40px; height: 40px;
  flex: none;
  border-radius: 50%;
  background: color-mix(in oklab, var(--npc-accent, var(--accent)) 20%, var(--bg-3));
  box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--npc-accent, var(--accent)) 45%, transparent);
  color: var(--npc-accent, var(--accent));
  font-family: var(--font-mono);
  font-size: var(--t-small);
  font-weight: 700;
}
.cr-from-meta { display: flex; flex-direction: column; line-height: 1.3; flex: 1; }
.cr-from-name { font-size: var(--t-small); font-weight: 600; }
.cr-from-role { font-size: var(--t-micro); color: var(--fg-dim); }
.cr-badge {
  padding: 4px 11px;
  border-radius: 99px;
  background: var(--warn-tint);
  color: var(--warn);
  font-family: var(--font-display);
  font-size: var(--t-micro);
  letter-spacing: .08em;
  text-transform: uppercase;
}

.cr-text {
  font-size: clamp(15px, 1.25vw, 18px);
  line-height: var(--lh-body);
  color: var(--fg);
  min-height: 3.4em;
}
.cr-text::after {
  content: '▌';
  color: var(--accent);
  animation: caret 1s step-end infinite;
}
.cr-text.is-complete::after { content: none; }
@keyframes caret { 50% { opacity: 0; } }

.cr-board { display: flex; flex-direction: column; gap: var(--s4); animation: phase-in var(--dur-slow) var(--ease-out) both; }
.cr-board-head { display: flex; align-items: baseline; gap: var(--s3); flex-wrap: wrap; }
.cr-board-hint { font-size: var(--t-small); color: var(--fg-dim); }

.cr-rack {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s3);
  min-height: 84px;
  padding: var(--s3);
  border-radius: var(--radius);
  background: var(--bg-inset);
  box-shadow: inset 0 0 0 1px var(--line);
  align-items: center;
}

.cr-contexts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: var(--s3);
  align-items: start;
}

.cr-zone {
  --ctx-color: var(--accent);
  display: flex;
  flex-direction: column;
  gap: var(--s3);
  padding: var(--s4);
  border-radius: var(--radius);
  background: var(--bg-1);
  box-shadow: inset 0 0 0 1px var(--line);
  min-height: 116px;
  transition: box-shadow var(--dur) var(--ease), background var(--dur) var(--ease);
}
.cr-zone.is-touched {
  background: color-mix(in oklab, var(--ctx-color) 10%, var(--bg-1));
  box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--ctx-color) 50%, transparent),
              0 0 26px color-mix(in oklab, var(--ctx-color) 12%, transparent);
}

.cr-zone-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--s2); }
.cr-zone-name {
  display: flex; align-items: center; gap: 6px;
  font-size: var(--t-small); font-weight: 600;
}
.cr-zone-name::before {
  content: '';
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--ctx-color);
}
.cr-zone-count { font-size: var(--t-micro); color: var(--fg-faint); }
.cr-zone-items { display: flex; flex-wrap: wrap; gap: 6px; flex: 1; align-content: flex-start; }
.cr-zone-empty { font-size: var(--t-micro); color: var(--fg-faint); font-style: italic; }

.cr-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s4);
  flex-wrap: wrap;
  padding-top: var(--s4);
  border-top: 1px solid var(--line);
}
.cr-foot-note { font-size: var(--t-small); color: var(--fg-dim); }

@media (max-width: 1023px) {
  .cr { padding-inline: var(--s4); }
  .cr-contexts { grid-template-columns: 1fr; }
}

/* Jazyk „art" — třetí doména (repertoár) používá umělecký slovník. */
.attribute--art { --attr-color: var(--sticky-policy); }
.attribute.is-placed.attribute--art::before { border-radius: 0; clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%); }

/* Jazyky pivovaru: řemeslo, sklad a řeč celní správy. Poslední má záměrně
   cizí barvu — je to model, který si pivovar nevymyslel. */
.attribute--craft  { --attr-color: var(--sticky-event); }
.attribute.is-placed.attribute--craft::before  { border-radius: 0; clip-path: polygon(50% 0, 100% 100%, 0 100%); }
.attribute--stock  { --attr-color: var(--ctx-0); }
.attribute.is-placed.attribute--stock::before  { border-radius: 2px; }
.attribute--excise { --attr-color: var(--sticky-hotspot); }
.attribute.is-placed.attribute--excise::before { border-radius: 0; clip-path: polygon(50% 0, 100% 38%, 82% 100%, 18% 100%, 0 38%); }
