/* Copyright 2026 G&G Technologies S.r.l. — SPDX-License-Identifier: PolyForm-Shield-1.0.0 */

/* The look of the block editor in `plan-editor.js`, and nothing else.
 *
 * It lives here for the same reason as its JavaScript: ever since the editor has lived in two apps,
 * one copy per app would be two stylesheets that drift apart — and they would drift in silence,
 * because no script compares two CSS files. Whoever uses it loads it after `base.css` and before
 * their own.
 *
 * **It uses only variables from `base.css`** — accent, borders, panels, fonts, radii — so it does
 * not declare a palette of its own and follows the theme of the app hosting it, light or dark. What
 * is left to the app is the layout around it: where the editor sits in the page, and how wide it is.
 */

/* The column of writing is the same width as the site's prose, and for the same reason: a line of
   text that runs the width of a desktop window is measurably harder to read, and the eye loses the
   start of the next line. */
.editor {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: 22px max(16px, calc(50% - 360px)) 40vh;
}

/* The tail of empty space under the last block is not a mistake: without it the final paragraph
   sits against the bottom of the window, and writing at the end of a long page means typing on the
   last visible line. */

.block { position: relative; display: flex; gap: 6px; align-items: flex-start; }

.block-body { flex: 1 1 auto; min-width: 0; }

/* The rail holds the `+`, and it is invisible until the pointer is near. It still occupies its
   width at all times: appearing and disappearing space would shift the text sideways as the mouse
   crosses it, which is worse than a faint button. */
/* The rail: two controls, side by side rather than stacked. Stacked they were two six-pixel marks
   in a column, and the one you wanted was always the other one — the handle in particular was a
   target smaller than the gap between the fingers holding the mouse. */
.block-rail {
  width: 52px;
  flex: none;
  padding-top: 2px;
  display: flex;
  align-items: flex-start;
  justify-content: flex-end;
  gap: 2px;
}

.rail-add, .rail-grip {
  opacity: 0;
  transition: opacity 120ms ease;
  color: var(--faint);
  border-radius: 6px;
  width: 24px;
  height: 24px;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
  font-size: 15px;
}

.rail-add:hover, .rail-grip:hover { background: rgba(127, 140, 170, 0.16); color: var(--text); }

/* Twenty-four pixels each, which is this catalogue's floor for anything you have to hit, and the
   handle carries a real grip pattern instead of the braille dots — at this size those read as
   dirt on the screen. */
.rail-grip {
  cursor: grab;
  touch-action: none;
  letter-spacing: 1px;
  font-size: 11px;
}

.dragging .rail-grip { cursor: grabbing; }

.block:hover .rail-add, .block:hover .rail-grip,
.rail-add:focus-visible, .rail-grip:focus-visible { opacity: 1; }

/* Half-visible on the block being written in, so the two controls are discovered by writing rather
   than by being told about — the block you are in is the block you are most likely to want to
   change, and a control nobody ever sees is a control that does not exist. */
.block:focus-within .rail-add, .block:focus-within .rail-grip { opacity: 0.55; }

@media (hover: none) {
  .rail-add, .rail-grip { opacity: 0.55; }
}

@media (prefers-reduced-motion: reduce) {
  .rail-add, .rail-grip { transition: none; }
}

/* While a block is being carried, the one it came from stays in place and fades: taking it out of
   the flow would make everything under it jump, and the line showing where it will land would be
   measured against a page that had already moved. */
.editor.dragging { cursor: grabbing; user-select: none; }

/* A link to a page that does not exist yet: dotted, so that the eye reads "to be made" before the
   hand clicks it. Clicking makes the page. */
.editor a.wiki.missing { text-decoration-style: dotted; opacity: 0.8; }

/* The hook to a project task: a small pill at the end of the line, not a piece of text. It says in
   one word how the task stands — "apri", "fatta", "eliminata" (open, done, deleted) — and opening it
   brings up its card. Small on purpose: the line is the sentence, this is its button. */
.editor a.task-link {
  display: inline-flex;
  align-items: center;
  margin-left: 6px;
  padding: 0 7px;
  height: 18px;
  border: 1px solid var(--border);
  border-radius: 999px;
  font-size: 11px;
  line-height: 1;
  color: var(--accent-text);
  text-decoration: none;
  vertical-align: 1px;
  user-select: none;
}
.editor a.task-link:hover { border-color: var(--accent); }
.editor a.task-link.done { color: var(--muted); }
/* Deleted from the board: the line stays, the hook says it no longer leads anywhere. */
.editor a.task-link.missing { color: var(--faint); border-style: dashed; }

/* The ✕ of the hooked line: small and muted until it is needed, like the ✕ of an appointment on the
   board. Always present and not only on mouse hover, because on a phone mouse hover does not exist
   and the control would never be found. */
.editor li .task-x {
  flex: none;
  margin-left: 2px;
  color: var(--faint);
  font-size: 12px;
  line-height: 1;
  min-height: 22px;
  min-width: 22px;
}
.editor li .task-x:hover { color: var(--late); }


/* A person named in the text: the accent, as the app paints people everywhere, and no underline —/* A person named in the text: the accent, as the app paints people everywhere, and no underline —/* A person named in the text: the accent, as the app paints people everywhere, and no underline —
   it is a name, not a link to be followed, though it opens the card when pressed. */
.editor a.mention {
  color: var(--accent-text);
  text-decoration: none;
  font-weight: 500;
  border-radius: 4px;
  padding: 0 2px;
  margin: 0 -2px;
}
.editor a.mention:hover { background: var(--accent-soft); }

/* The people menu holds names only: no sample column. */
.menu-entry.person { grid-template-columns: 1fr; }

.block.lifted { opacity: 0.4; }

/* Where it will land: a line with a dot at its head, so it reads as a place and not as a border
   somebody drew by accident. */
.drop-line {
  position: absolute;
  left: 52px;
  right: 0;
  height: 2px;
  background: linear-gradient(90deg, var(--accent), var(--accent-text));
  border-radius: 1px;
  pointer-events: none;
  z-index: 5;
}

.drop-line::before {
  content: "";
  position: absolute;
  left: -5px;
  top: -3px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--accent);
}

.editor { position: relative; }

/* ---- the strip over a selection */

.mark-bar {
  position: fixed;
  z-index: 30;
  display: flex;
  gap: 2px;
  padding: 4px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--panel-2);
  box-shadow: 0 8px 22px rgba(0, 0, 0, 0.30);
}

.mark-bar button {
  border-color: transparent;
  min-width: 30px;
  padding: 4px 6px;
  line-height: 1.1;
}

.mark-bar button:hover { background: rgba(127, 140, 170, 0.14); }

.mark-bar code { font-size: 12px; }

.block [contenteditable] {
  outline: none;
  min-height: 1.5em;
  padding: 2px 0;
  overflow-wrap: anywhere;
}

.block [contenteditable]:focus { outline: none; }

.block .h { font-family: var(--font-display); font-weight: 400; line-height: 1.25; }

.block .h1 { font-size: 27px; margin-top: 14px; }

.block .h2 { font-size: 21px; margin-top: 12px; }

.block .h3 { font-size: 17px; margin-top: 10px; }

.md-list { margin: 0; padding-left: 22px; }

.md-list li { margin: 1px 0; display: flex; gap: 8px; align-items: flex-start; }

.md-list li .item { flex: 1 1 auto; }
/* Next to the pill and not at the end of the line: the field takes all the space it finds, and
   without this rule the ✕ ended up at the right margin, far from the thing it deletes. */
.md-list li:has(.task-x) .item { flex: 0 1 auto; }

/* An `li` laid out as flex loses the browser's own marker, and it has to be flex to hold the tick
   beside the text. So an ordered list counts for itself, starting where the source said. */
ol.md-list { list-style: none; padding-left: 4px; counter-reset: md-item; }

ol.md-list > li { counter-increment: md-item; }

ol.md-list > li::before {
  content: counter(md-item) ".";
  color: var(--faint);
  min-width: 20px;
  padding-top: 2px;
  flex: none;
  font-variant-numeric: tabular-nums;
}

/* In the editor a ticked item is struck with `text-decoration`, not with the drawn line the task
   list uses. There the element hugs its own text; here it is the editable field and has to span the
   row to be clickable, so the drawn line would run to the far edge — the same defect twice, and the
   second time in a place where the fix could not be the same. */
.md-list li .item.struck {
  background-image: none;
  animation: none;
  text-decoration: line-through;
}

/* The bullet is the site's own square in the accent gradient, not the browser's dot — the same mark
   the pages and the article illustrations use. */
ul.md-list { list-style: none; padding-left: 4px; }

ul.md-list li:not(:has(.tick))::before {
  content: "";
  width: 6px;
  height: 6px;
  margin-top: 9px;
  flex: none;
  border-radius: 1px;
  background: linear-gradient(135deg, var(--accent), var(--accent-text));
}

.md-list .depth-1 { margin-left: 22px; }
.md-list .depth-2 { margin-left: 44px; }
.md-list .depth-3 { margin-left: 66px; }
.md-list .depth-4 { margin-left: 88px; }
.md-list .depth-5 { margin-left: 110px; }
.md-list .depth-6 { margin-left: 132px; }

.block .quote {
  padding-left: 14px;
  border-left: 2px solid var(--border-strong);
  color: var(--muted);
}

/* The callout is the site's highlighted panel, recipe unchanged: the gradient, the hairline border,
   the 2px filament of accent along the top. */
.callout {
  position: relative;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: linear-gradient(170deg, var(--panel-2), var(--panel) 60%);
  padding: 14px 16px 12px;
  overflow: hidden;
}

.callout::before {
  content: "";
  position: absolute;
  inset: 0 auto auto 0;
  width: 100%;
  height: 2px;
  background: linear-gradient(90deg, var(--accent), var(--accent-text));
}

.callout-kind {
  display: block;
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent-text);
  margin-bottom: 4px;
}

.block-divider { border: 0; border-top: 1px solid var(--border-strong); margin: 18px 0; }

.block-code, .block-raw {
  background: rgba(127, 140, 170, 0.10);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 10px 12px;
  margin: 0;
  overflow-x: auto;
}

.block-code code, .block-raw code {
  display: block;
  font-family: var(--font-mono);
  font-size: 13px;
  white-space: pre-wrap;
}

/* Raw is what this app has no block for — HTML, a footnote, a heading deeper than three. It is
   shown as what it is rather than dressed up as prose, and it is written back untouched. */
.block-raw { background: transparent; border-style: dashed; color: var(--faint); }

.block-table { border-collapse: collapse; width: 100%; font-size: 14px; }

.block-table th, .block-table td {
  border: 1px solid var(--border);
  padding: 4px 8px;
  text-align: left;
  vertical-align: top;
}

.block-table th { background: rgba(127, 140, 170, 0.08); font-weight: 500; }

.block-image img { max-width: 100%; height: auto; border-radius: var(--radius-sm); }

.block-image { margin: 6px 0; }

.block a { color: var(--accent-text); }

.block code { font-family: var(--font-mono); font-size: 0.92em; }

.menu-list { display: grid; gap: 2px; margin: 12px 0; max-height: 54vh; overflow-y: auto; }

/* Each entry shows the thing as well as its name. A list of names asks somebody to know what a
   «callout» is before they can choose one; a line of the real thing tells them. */
.menu-entry {
  border-color: transparent;
  text-align: left;
  padding: 6px 10px;
  display: grid;
  grid-template-columns: 132px 1fr;
  align-items: center;
  gap: 12px;
}

.menu-entry:hover, .menu-entry:focus-visible { background: rgba(127, 140, 170, 0.12); }

/* The one the block already is, so «turn into» says what it is turning *from*. */
.menu-entry.on { border-color: var(--accent); background: var(--accent-soft); }

.menu-name { font-size: 13.5px; }

.sample {
  display: flex;
  align-items: center;
  gap: 6px;
  height: 26px;
  padding: 0 8px;
  border-radius: var(--radius-sm);
  background: rgba(127, 140, 170, 0.10);
  overflow: hidden;
}

.sample-text {
  font-size: 12px;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.sample .h { font-family: var(--font-display); }

.sample .h1 { font-size: 16px; }
.sample .h2 { font-size: 14px; }
.sample .h3 { font-size: 12.5px; }

.sample-dot {
  width: 5px;
  height: 5px;
  flex: none;
  border-radius: 1px;
  background: linear-gradient(135deg, var(--accent), var(--accent-text));
}

.sample-num { font-size: 11px; color: var(--faint); flex: none; }

.sample-box {
  width: 11px;
  height: 11px;
  flex: none;
  border: 1px solid var(--border-strong);
  border-radius: 3px;
}

.sample-quote { border-left: 2px solid var(--border-strong); padding-left: 6px; }

.sample-callout { border-top: 2px solid var(--accent); background: var(--accent-soft); }

/* A decision keeps the panel and changes only its word: the colour of what is still to be decided,
   which the app defines as `--decide`. An app without it gets the accent, and loses nothing. */
.callout-decisione .callout-kind { color: var(--decide, var(--accent-text)); }
.sample-decision { border-top-color: var(--decide, var(--accent)); }

.sample-code { font-family: var(--font-mono); font-size: 11px; color: var(--muted); }

.sample-rule { flex: 1 1 auto; height: 1px; background: var(--border-strong); }

.sample-table {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  width: 100%;
  height: 15px;
}

.sample-table span { background: var(--border-strong); border-radius: 1px; }

#blockMenuField { width: 100%; }

/* Under the last block: a click here goes on writing at the bottom of the document. */
.editor-tail { min-height: 72px; cursor: text; }
