/* editor.css — block rows. Each .txt is its own contenteditable (DESIGN.md §4). */

.doc { max-width: 42em; margin: 0 auto; counter-reset: ol0 ol1 ol2 ol3; }

.row { position: relative; display: flex; align-items: flex-start; }
.row .txt {
  font-family: var(--note-font, var(--font));     /* the font selector (ui/font.js) */
  flex: 1;
  min-width: 0;
  outline: none;
  white-space: pre-wrap;
  tab-size: 5;             /* engines without length support */
  tab-size: var(--step);   /* one typed tab = one indent step, exactly */
  overflow-wrap: break-word;
  padding: 1px 0;
  caret-color: var(--accent-ink);
}
.row .txt:empty::before {
  content: attr(data-ph);
  color: var(--ink-3);
  pointer-events: none;
}

/* ONE LEFT EDGE (Gianni, 2026-10-19: "none should ever break the same horizontal
   spacing unless its specifically text size/title").

   Every row reserves the same gutter, --gut. Bullets, numbers, checkboxes and the quote
   bar HANG in it, so the text of every style starts at the same x: switching a line
   between body, bullet, checklist, quote or code never moves its words sideways. Only
   headings change, and only in size.

   Depth moves text by --step, and a typed tab is exactly --step wide (tab-size takes the
   same length), so a tab-indented body line and a level-1 bullet line up exactly. A new
   style added later only has to put its marker in the gutter. */
:root { --step: 24px; }                   /* one indent level, and the width of one typed tab */
.doc { --gut: 22px; --mk-gap: 4px; }

/* --ind: how far in a row's text sits, in steps: its list depth plus its leading tabs */
.row { --ind: var(--d, 0); padding-left: calc(var(--gut) + var(--ind) * var(--step)); }
.row[data-tabs] { --ind: calc(var(--d, 0) + var(--tabs)); }
.row[data-tabs] > .txt { text-indent: calc(-1 * var(--tabs) * var(--step)); }
.row[data-depth="1"] { --d: 1; }
.row[data-depth="2"] { --d: 2; }
.row[data-depth="3"] { --d: 3; }

/* one vertical rhythm for every style that is not a heading */
.row .txt { margin: .12em 0; }

/* headings: size only */
.row[data-t="h1"] .txt { font-size: 1.6em; font-weight: 700; letter-spacing: -.02em; margin: .5em 0 .1em; }
.row[data-t="h2"] .txt { font-size: 1.27em; font-weight: 700; letter-spacing: -.01em; margin: .45em 0 .1em; }
.row[data-t="h3"] .txt { font-size: 1.08em; font-weight: 600; margin: .4em 0 .1em; }

/* the marker column: right-aligned against the text, on its first line */
.row[data-t="li"]::before,
.row[data-t="ol"]::before {
  position: absolute;
  top: calc(1px + .12em);
  left: calc(var(--ind) * var(--step));
  width: calc(var(--gut) - var(--mk-gap));
  text-align: right;
  line-height: var(--lh);
  color: var(--accent-ink);
}
.row[data-t="li"]::before { content: "•"; }
/* ONE bullet (Gianni, 2026-10-19: "combine like things into one - bullets (alternating
   filled and hollow for indents)"): the level picks the marker, filled and hollow in
   turn. Depth is already stored, so this is presentation only and every build agrees
   on the data (the merge's old "hyphens" are simply level-1 bullets, now hollow). */
.row[data-t="li"][data-depth="1"]::before,
.row[data-t="li"][data-depth="3"]::before { content: "◦"; }

/* numbers count per level: a nested list starts at 1, and its parent carries on */
.row:not([data-t="ol"]) { counter-reset: ol0 ol1 ol2 ol3; }
.row[data-t="ol"] { counter-increment: ol0; counter-reset: ol1 ol2 ol3; }
.row[data-t="ol"][data-depth="1"] { counter-increment: ol1; counter-reset: ol2 ol3; }
.row[data-t="ol"][data-depth="2"] { counter-increment: ol2; counter-reset: ol3; }
.row[data-t="ol"][data-depth="3"] { counter-increment: ol3; counter-reset: none; }
.row[data-t="ol"]::before { content: counter(ol0) "."; font-variant-numeric: tabular-nums; }
/* ONE numbered list: numbers, then letters, then roman, by level ("numbered/lettered
   lists" combined) */
.row[data-t="ol"][data-depth="1"]::before { content: counter(ol1, lower-alpha) "."; }
.row[data-t="ol"][data-depth="2"]::before { content: counter(ol2, lower-roman) "."; }
.row[data-t="ol"][data-depth="3"]::before { content: counter(ol3) "."; }

.row[data-t="check"] > .chk {
  position: absolute;
  left: calc(var(--ind) * var(--step) + var(--gut) - var(--mk-gap) - 18px);
  top: calc(1px + .12em + (1em * var(--lh) - 18px) / 2);
  width: 18px; height: 18px;
  border: 1.7px solid var(--ink-3);
  border-radius: 50%;
  display: grid; place-items: center;
}
.row[data-t="check"] > .chk[aria-pressed="true"] {
  background: var(--accent);
  border-color: var(--accent);
}
.row[data-t="check"] > .chk svg { width: 11px; height: 11px; stroke: var(--on-accent); stroke-width: 2.6; fill: none; opacity: 0; }
.row[data-t="check"] > .chk[aria-pressed="true"] svg { opacity: 1; }
.row[data-t="check"][data-done="1"] .txt { color: var(--ink-3); text-decoration: line-through; }

/* quote: the bar hangs in the gutter; consecutive quote lines join into one bar */
.row[data-t="quote"]::before {
  content: "";
  position: absolute;
  top: 0; bottom: 0;
  left: calc(var(--ind) * var(--step) + var(--gut) - var(--mk-gap) - 3px);
  width: 3px;
  border-radius: 2px;
  background: var(--accent);
}
.row[data-t="quote"]:has(+ .row[data-t="quote"])::before { border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
.row[data-t="quote"] + .row[data-t="quote"]::before { border-top-left-radius: 0; border-top-right-radius: 0; }
.row[data-t="quote"] .txt { color: var(--ink-2); font-style: italic; }

/* code: the panel reaches into the gutter by exactly its own padding, so the text keeps
   the common left edge; consecutive code lines join into one panel */
.row[data-t="code"] .txt {
  font: .88em/1.5 var(--mono);
  white-space: pre-wrap;
  background: var(--paper-2);
  margin-left: -8px;
  padding: 3px 8px;
  border-radius: 7px;
}
.row[data-t="code"]:has(+ .row[data-t="code"]) .txt { margin-bottom: 0; border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
.row[data-t="code"] + .row[data-t="code"] .txt { margin-top: 0; border-top-left-radius: 0; border-top-right-radius: 0; }

/* callout: a tinted panel; like code, it reaches into the gutter by exactly its own
   padding, so its text keeps the common left edge. Consecutive callout lines join. */
.row[data-t="callout"] .txt {
  background: color-mix(in srgb, var(--accent) 14%, var(--paper));
  margin-left: -8px;
  padding: 3px 8px;
  border-radius: 7px;
}
.row[data-t="callout"]:has(+ .row[data-t="callout"]) .txt { margin-bottom: 0; border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
.row[data-t="callout"] + .row[data-t="callout"] .txt { margin-top: 0; border-top-left-radius: 0; border-top-right-radius: 0; }

/* small: a size change only, on the common edge */
.row[data-t="small"] .txt { font-size: .82em; color: var(--ink-2); }

/* inline marks */
.m-b { font-weight: 700; }
.m-i { font-style: italic; }
.m-u { text-decoration: underline; }
.m-s { text-decoration: line-through; }
.m-u.m-s { text-decoration: underline line-through; }
.m-hl { background: var(--hl); border-radius: 3px; box-decoration-break: clone; -webkit-box-decoration-break: clone; }
.m-red { color: var(--red); }
.m-code {
  font: .89em var(--mono);
  letter-spacing: .06em;      /* a little more air between letters, whatever the note's font (Gianni, 2026-10-19) */
  background: var(--paper-2);
  border: 1px solid var(--rule);
  border-radius: 4px;
  padding: 0 4px;
}

/* The first block of a note reads as its title, the way iOS Notes does it —
   without being a distinct block type, so the model stays uniform and the
   denormalised `title` column is just "first non-empty line". An explicit
   type on the first block still wins. */
.doc > .row:first-child[data-t="p"] .txt {
  font-size: 1.45em;
  font-weight: 700;
  letter-spacing: -.02em;
  margin: 0 0 .15em;
}

/* A block from a newer build (schema.js isOpaque): visible, read-only, unmistakably so. */
.row.opaque .txt { color: var(--ink-3); font-style: italic; cursor: default; -webkit-user-select: none; user-select: none; }

/* links: the mark has always been stored; it was never drawn */
.m-link { color: var(--accent-ink); text-decoration: underline; text-underline-offset: 2px; }

/* the checkbox fills on the same 150 ms curve as everything else */
.row[data-t="check"] > .chk { transition: background var(--dur) var(--ease-smoother), border-color var(--dur) var(--ease-smoother); }
.row[data-t="check"] > .chk svg { transition: opacity var(--dur) var(--ease-smoother); }

/* checklist steps: a quarter, a half, three quarters (doc.js stepOf) */
.row[data-t="check"][data-p] > .chk { border-color: var(--accent); }
.row[data-t="check"][data-p="1"] > .chk { background: conic-gradient(var(--accent) 0 25%, transparent 0); }
.row[data-t="check"][data-p="2"] > .chk { background: conic-gradient(var(--accent) 0 50%, transparent 0); }
.row[data-t="check"][data-p="3"] > .chk { background: conic-gradient(var(--accent) 0 75%, transparent 0); }

/* the five steps, shown while a checkbox is held */
.chksteps {
  position: fixed; z-index: 45;
  display: flex; gap: 4px; padding: 5px;
  border-radius: 999px;
  background: var(--paper);
  border: 1px solid var(--rule);
  box-shadow: 0 6px 20px rgba(0,0,0,.18);
}
.chkstep {
  width: 34px; height: 34px; border-radius: 50%;
  border: 1.7px solid var(--accent);
  background: var(--paper);
}
.chkstep[data-step="1"] { background: conic-gradient(var(--accent) 0 25%, var(--paper) 0); }
.chkstep[data-step="2"] { background: conic-gradient(var(--accent) 0 50%, var(--paper) 0); }
.chkstep[data-step="3"] { background: conic-gradient(var(--accent) 0 75%, var(--paper) 0); }
.chkstep[data-step="4"] { background: var(--accent); }
.chkstep[data-step="0"] { border-color: var(--ink-3); }
.chkstep[aria-checked="true"] { box-shadow: 0 0 0 2px var(--paper), 0 0 0 4px var(--ink-2); }
.chkstep.hot { transform: scale(1.15); }

/* a partly done line wears its progress: a soft bar behind the text, a quarter, a half
   or three quarters across (Gianni, 2026-10-19: "a subtle background fill as percent") */
.row[data-t="check"][data-p] .txt {
  margin-left: -4px; padding-left: 4px; padding-right: 4px;   /* keeps the text on the common edge */
  border-radius: 5px;
  background-repeat: no-repeat;
  background-image: linear-gradient(color-mix(in srgb, var(--accent) 16%, transparent), color-mix(in srgb, var(--accent) 16%, transparent));
}
.row[data-t="check"][data-p="1"] .txt { background-size: 25% 100%; }
.row[data-t="check"][data-p="2"] .txt { background-size: 50% 100%; }
.row[data-t="check"][data-p="3"] .txt { background-size: 75% 100%; }

/* the whole-line hold, shown on the line itself: a tint sweeps across it while the
   footer button charges, and the line flashes when the style lands */
.row.line-charging .txt { position: relative; }
.row.line-charging .txt::after {
  content: ""; position: absolute; left: -4px; right: -4px; top: 0; bottom: 0;
  border-radius: 5px;
  background: color-mix(in srgb, var(--accent) 30%, transparent);
  transform-origin: left center;
  animation: line-sweep var(--line-ms, 450ms) linear forwards;
  pointer-events: none;
}
@keyframes line-sweep { from { transform: scaleX(0); } to { transform: scaleX(1); } }
.row.line-done .txt { animation: line-flash 500ms var(--ease-smoother); border-radius: 5px; }
@keyframes line-flash { from { background: color-mix(in srgb, var(--accent) 45%, transparent); } to { background: transparent; } }
