/* The kanban board: columns, cards, drag and drop. */

/* ----------------------------------------------------------------- kanban */

/* The board fills the screen and its columns stretch to the same height, so
   the tint on a drop target covers the whole column, not just its cards. */
.board-wrap {
  display: flex;
  flex-direction: column;
}

/* The board, with a folded column standing at either end of it. */
.board-row {
  display: flex;
  align-items: stretch;
  gap: 16px;
  flex: 1;
  min-height: 0;
}

/* A folded column is a divider, not a second panel: the element IS the rule,
   so it takes no column width of its own. Its heading lies across it, centred
   on the line, and breaks the rule where the words sit. */
.colstrip {
  position: relative;
  flex: none;
  width: 3px;
  margin: 20px 0;
  border-radius: 3px;
  background: var(--ink);
  text-decoration: none;
  color: var(--ink-text);
}

/* Out of the flow and turned a quarter, so the name reads bottom to top and
   sits astride the rule rather than beside it. The strip is three pixels wide,
   so a shrink-to-fit box would collapse inside it: the heading takes its own
   content width and is then centred by hand, half its size back on each axis,
   turned about that centre. */
.colstrip .colhead {
  position: absolute;
  top: 50%;
  left: 50%;
  width: max-content;
  transform: translate(-50%,-50%) rotate(-90deg);
  transform-origin: 50% 50%;
  background: var(--ink);
  padding: 1.5px 10px 1.5px 7px;
  white-space: nowrap;
  font-weight: 600;
  border-radius: 10px;
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* On the strip the mark sits on the ink, not on the column's own surface, so
   it drops its column colour and is drawn in the ink's own contrast colour:
   the ring for Идеи, and the disc for Готови — whose tick, white against the
   green, is turned back to the ink so it stays legible on the light disc.
   Only while the column is folded; open columns keep their colours. */
.colstrip .statemark {
  color: var(--ink-text);
}

.colstrip .statemark path {
  stroke: var(--ink);
}


.board {
  display: grid;
  grid-template-columns: repeat(auto-fit,minmax(0,1fr));
  gap: 16px;
  align-items: stretch;
  flex: 1;
  min-width: 0;
}

/* Each column is its own soft panel; the cards sit white on top of it. */
.col {
  display: flex;
  flex-direction: column;
  min-height: 200px;
  padding: 10px;
  border-radius: 14px;
  background: var(--card2);
  transition: background .15s;
}

.col > header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  font-size: 14px;
  font-weight: 600;
  margin: 2px 0 10px;
  padding: 0 4px 0 6px;
}

/* The cards scroll inside their column, not the page. The scroller keeps
   8px above the first card so the drop line before it is not clipped, and
   its thumb takes the column's colour.

   The scroller reaches 5px into the column's own 10px padding and gives that
   5px back as padding, so the cards keep their width while the bar sits in
   the middle of the grey strip beside them instead of against the cards. */
.zone-scroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;

  padding: 0 5px 8px 0;
  margin-right: -5px;
}

.zone-scroll::-webkit-scrollbar {
  width: 5px;
}

.zone-scroll::-webkit-scrollbar-track {
  background: transparent;
  margin-bottom: 8px;
}

.zone-scroll::-webkit-scrollbar-thumb {
  background: var(--c, var(--muted));
  border-radius: 50em;
}
/* On the Задачи page and on a project page the board fills the window down
   to 28px from its bottom; the page itself no longer scrolls, each column
   does. On the project page the header and the cards above take their own
   height first and the board gets the rest, but never less than 320px: on a
   short window the page scrolls that little bit instead of squashing the board. */
@media (min-width:1101px) {
  main:has(> [data-board-page]) {
    height: calc(100vh - 68px);
    min-height: 0;
    padding-bottom: 28px;
    overflow: hidden auto;
  }

  main:has(> [data-board-page]) > * {
    flex: none;
  }

  [data-board-page].board-wrap {
    flex: 1;
    min-height: 320px;
  }

  [data-board-page] .board,
  [data-board-page] .col {
    min-height: 0;
  }
}

/* The zone's radius is the card radius (16px) plus the 2px gap, so the dashed
   outline stays exactly 2px from a card all the way round the corner. */
.col .zone {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-height: 40px;
  border-radius: 16px;
}

/* A card is a link on hover (a click opens it) and a grab while the mouse is
   held down or the card is being dragged. */
/* Every card keeps the 3px top edge so they are all the same height; only
   the types worth spotting from across the board paint it (see below). */
/* Every card looks the same; what needs attention says so with a chip, not
   with a coloured edge. */
.tcard {
  background: var(--card);
  border-radius: 8px;
  padding: 10px 12px 12px;
  cursor: pointer;
}

.tcard:active,
.tcard.dragging {
  cursor: grabbing;
}

/* While a card is carried, the closed hand stays everywhere on the page and
   a ghost copy of the card follows the pointer. */
body.is-dragging,
body.is-dragging * {
  cursor: grabbing !important;
}

body.is-dragging {
  user-select: none;
  -webkit-user-select: none;
}

.tcard-ghost {
  position: fixed;
  z-index: 1000;
  pointer-events: none;
  opacity: .95;
  box-shadow: 0 18px 44px rgba(0,0,0,.18);
  transform-origin: var(--ox,50%) var(--oy,50%);
  transform: scale(.95);
  animation: ghost-in .18s ease-out both;
}

/* The ghost is created already scaled, so the shrink is an animation from
   full size rather than a transition: it plays the moment the ghost appears. */
@keyframes ghost-in {
  from {
    transform: scale(1);
  }
  to {
    transform: scale(.95);
  }
}

.tcard.dragging {
  opacity: .5;
}

/* Where the card will land, in the colour of the column it is over (--c is set on the zone). Shown only while a drag is in progress. */

/* Absolutely positioned so it sits inside the gap between cards and never
   pushes anything. Its top is set by script to the middle of that gap.
   6px tall with fully rounded ends, in the colour of the column. */
.dropline {
  position: absolute;
  left: 5px;
  right: 5px;
  height: 6px;
  border-radius: 999px;
  background: var(--c,var(--ink));
  pointer-events: none;
  z-index: 2;
}

/* The column a card is dragged over is tinted with its own colour at 10%. */
.col.over {
  background: color-mix(in srgb,var(--c,var(--muted)) 10%,var(--card));
}

.tcard .top {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 7px;
}

/* Project name (and the employer chip after it) take what is left of the
   row; the name truncates so the date on the right never wraps. */
.tcard .top .proj {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: 1 1 0;
  min-width: 0;
}

.tcard .top .proj > .sub {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tcard .title {
  font-size: 14px;
  font-weight: 500;
}

/* The card shows the opening of the note, not the note. A board stays open
   all day in front of whoever walks past, and a note is where access details
   end up; three lines and an ellipsis are enough to recognise which note it
   is, and the whole text is one click away in the task popup. Only the height
   is constrained here: size, colour and margin are the same as before. */
.tcard .note {
  font-size: 12px;
  color: var(--muted);
  margin-top: 4px;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  overflow: hidden;
}

/* -------------------------------------------------------- task priority */

/* One colour per priority, read through --t by everything that shows one: the
   flag on a card, the flag in the task popup and the one in the form's select.
   Red for urgent, amber for high, grey for low. Normal work shows no flag at
   all, so it needs no colour: a mark every task wears says nothing. */
[data-priority="urgent"] { --t: var(--red); }
[data-priority="high"]   { --t: var(--orange); }
[data-priority="normal"] { --t: var(--blue); }
[data-priority="low"]    { --t: var(--muted); }

/* The flag takes the colour of its priority; the beetle is always red,
   because a bug is one thing and not a step on that scale. */
.tchip.prio,
.tchip.bug {
  padding: 0 5.5px;
}

.tchip.prio {
  background: color-mix(in srgb,var(--t) 12%,var(--card));
}

.tchip.prio svg {
  color: var(--t);
}

.tchip.bug {
  background: color-mix(in srgb,var(--red) 12%,var(--card));
}

.tchip.bug svg {
  color: var(--red);
}

/* ------------------------------------------------------------ responsive */
@media (max-width:1100px) {
  .board {
    grid-template-columns: repeat(2,minmax(0,1fr));
  }
}

@media (max-width:900px) {
  .board {
    grid-template-columns: 1fr;
  }
  .col {
    min-height: 0;
  }
}

/* The state mark of a column: in its heading, and in front of a task row on
   the dashboard. Its colour comes from --c, set where it is used. */
.statemark {
  display: inline-flex;
  color: var(--c,var(--muted));
  flex: none;
}

.statemark svg {
  display: block;
}

.colhead {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

/* The count and the add button share the right end of the column header. */
.colside {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex: none;
}

/* Adding a task starts here rather than at the foot of the column, so it is
   in reach whatever the column holds. A ghost button until it is hovered. */
/* The two controls in a column heading: fold the column away, and add a task
   to it. Same shape and same weight, so neither shouts over the other. */
.coladd,
.colfold {
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  border-radius: 8px;
  padding: 0;
  background: transparent;
  /* Both are drawn in the text colour: the frame is thin enough that a muted
     grey read as faded next to the solid plus beside it. */
  color: var(--text);
  text-decoration: none;
  text-transform: none;
  letter-spacing: normal;
}

.coladd:hover,
.colfold:hover {
  background: var(--card);
  color: var(--text);
  box-shadow: none;
}

.coladd svg,
.colfold svg {
  display: block;
}


/* The frame is drawn for the column at the left end; the one at the right end
   is the same glyph flipped. */
.mirror svg {
  transform: scaleX(-1);
}

.due {
  font-size: 12px;
  font-weight: 500;
  white-space: nowrap;
}

/* The row of chips under the card text: overdue mark, deadline, checklist
   progress and attachments, each on its own light grey ground. */
.tcard .tcard-meta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 10px;
}

.tchip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  height: 24px;
  padding: 0 7px;
  border-radius: 8px;
  background: var(--chip-bg,var(--card2));
  font-size: 11px;
  font-weight: 500;
  color: var(--text);
  white-space: nowrap;
}

/* On a grey row the plain chip takes a white ground so it does not sink into
   the row, and everything a row shows reads at one size, 14px. The tinted
   chips below set their own ground and keep it. */
.row .tchip {
  --chip-bg: var(--card);
  height: 28px;
  padding: 0 9px;
  font-size: 14px;
}

/* At 14px the mark grows with the label instead of staying at its card size. */
.row .tchip svg {
  width: 1em;
  height: 1em;
}

.tchip svg {
  width: 13px;
  height: 13px;
  flex: none;
  color: inherit;
}

/* The siren is a chip of its own: red on a light red ground once the task is
   late, amber in the three days before the deadline. */
.tchip.late,
.tchip.soon {
  padding: 0 5.5px;
}

.tchip.late {
  background: color-mix(in srgb,var(--red) 12%,var(--card));
}

.tchip.soon {
  background: var(--orange-bg);
}

.tchip.green {
  background: color-mix(in srgb, var(--green) 10%, var(--card));
  color: var(--green-ink);
}

/* Checklist on the card, as in KanbanFlow: up to five items at the bottom,
   under a dashed rule, each with a small round tick that works in place. */
.tcard-checks {
  list-style: none;
  margin: 10px 0 0;
  padding: 8px 1px 0;
  border-top: 1px dashed var(--line);
  display: flex;
  flex-direction: column;
  gap: 6px;
}

/* A long item wraps instead of being cut; the tick stays with the first
   line, nudged to sit centred on it. */
.tcard-checks label {
  display: flex;
  align-items: flex-start;
  gap: 7px;
  margin: 0;
  font-size: 12px;
  line-height: 1.4;
  color: var(--text);
  cursor: pointer;
}

/* 14px box, 24px target: the ticks sit 6px apart in a column, so the reach
   stops at 5px on every side rather than the 8px a coarse pointer gets
   elsewhere - otherwise neighbouring items would overlap each other. */
.tcard-checks input[type=checkbox] {
  width: 14px;
  height: 14px;
  margin-top: 1.5px;
}

.tcard-checks input[type=checkbox]::after {
  inset: -5px;
}

.tcard-checks input[type=checkbox]::before {
  width: 6px;
  height: 4px;
  border-width: 0 0 1.5px 1.5px;
}

.tcard-checks span {
  min-width: 0;
  overflow-wrap: anywhere;
}

.tcard-checks li.done span {
  color: var(--muted);
}

.tcard-checks li.more {
  font-size: 11px;
  color: var(--muted);
  padding-left: 21px;
}

/* The overdue calendar icon is exactly the size of the text beside it and
   sits on its line, in the text's colour. Inline text gets a small gap after
   it; the flex tags (.money-row .late, .spaced-tag) already use gap. */
.next.late svg,
.money-row .late svg,
.spaced-tag svg {
  width: 1em;
  height: 1em;
  flex: none;
}

.next.late svg {
  vertical-align: -0.15em;
  margin-right: 0.3em;
}
