/* ─────────────────────────────────────────────────────────────────────────────
   LOGIC
   The company as one tree on a board you can pan and zoom, opened and closed in place.

   Part 13 of 14. THE ORDER OF THESE FILES IS LOAD-BEARING — the list lives in
   lib/app_css.php and this sits before responsive.css, which overrides.

   THE TWO HEADINGS THAT USED TO BE HERE WERE BOTH FALSE, and each had been for
   several versions. "Phone first, a single column that grows downwards" describes
   v8; depth has gone RIGHTWARD since v14 and the phone rules are one media query
   at the end like everybody else's. "The lines are CSS, not SVG" describes the
   elbows this file used to draw; a CSS elbow can only reach a sibling, and the
   shape now crosses a gap whose size changes, so every edge is measured SVG drawn
   by drawEdges() in js/views/logic.js. A stale header is worse than none: both of
   these were read as instructions and cost a release each.

   ONE MODULE WIDTH — 320px — for cards, ledger boxes and drawers alike, and ONE
   TEXT AXIS: 16px inset, a 12px caret gutter, a 3px rule, 10px gaps. Every label
   on this screen begins 52px from its card's left edge, at every depth, in every
   state. Change any of those four numbers and change them together.

   EVERY CLASS IS lg-*. Text wears ink tokens; the palette lives on the ticks, and
   what the palette may be is measured in js/views/logic.js — ≥3:1 on both surfaces.
   ───────────────────────────────────────────────────────────────────────────── */

/* THE LENS SWITCH IS THE HOUSE HEADLINE SWITCHER (.seg-tabs) and the mode switch is
   the house segmented control (.toggle-group) — both live in views/logic.php's header,
   styled by lists.css and chrome.css exactly as they are on Projects and People. This
   file used to carry its own pill rail, which made Logic the one screen in the app
   that looked like it came from a different product. */

/* FLUSH LEFT, like the diagram under it. The tree grows rightward from a left edge, so
   a centred paragraph above it would put the page on two different axes. */
.lg-lede {
    font-size: 12.5px; line-height: var(--leading-relaxed);
    margin: 0 0 18px; max-width: 68ch;
}
/* FOUR LENSES, NOT TWO. The house headline switcher is 26px on a phone, which is right
   for the Projects/People pair but wraps Logic's four names onto a second line — the
   page title becoming two lines of title. Same control, one size down. */
@media (max-width: 680px) {
    #logic-lenses .seg-tab { font-size: 19px; }
    #logic-lenses { gap: 14px; }
}
/* THE PAGE IS THE FORMAT, AND THE GRID IS DRAWN INSIDE IT.
   The page takes the full measure the shell allows and the SHEET decides how much of it
   to use — modules are a fixed width set by js/views/logic.js, so a lens that needs one
   column gets one column and white space, not a 1200px row with its figure a screen away
   from its label. The lede keeps its own reading measure regardless. */
/* ── THE WHOLE VIEWPORT IS THE BOARD ──────────────────────────────────────────
   Nothing above it, nothing beside it, nothing below it. The page had a 24px gutter each
   side and a 117px header band before the canvas started, so the diagram was a rectangle
   inside a document rather than the surface the document is made of.

   The controls now float ON the board — the lens switch, the period, the zoom — the way
   a toolbar sits on a canvas everywhere else this interaction exists. The board is pulled
   up under them and bled out to both screen edges; the tree keeps clear of the header
   through the stage's own top padding, so panning never buries a card under the title. */
.lg-page { max-width: none; padding: 0; }
#view-logic .lg-head-float { position: relative; z-index: 6; pointer-events: none; }
#view-logic .lg-head-float > * { pointer-events: auto; }
/* THE CONTROLS NEED SOMETHING TO STAND ON. They float over the board, so panning brings
   cards up underneath them — and with nothing behind the type, a card and the page title
   were drawn through each other. A wash of the page's own colour, fading out at the
   bottom edge so it never reads as a bar: content slides BEHIND the header instead of
   colliding with it, which is the whole reason a toolbar may sit on a canvas at all.
   Bled to both screen edges and up over the nav, because the board is. */
#view-logic .lg-head-float::before {
    content: ''; position: absolute; z-index: -1; pointer-events: none;
    left: 50%; width: 100vw; transform: translateX(-50%);
    top: -40px; bottom: -26px;
    background: linear-gradient(to bottom,
        var(--bg-main) 0%, var(--bg-main) 66%, rgba(244, 244, 245, 0) 100%);
}
@media (prefers-color-scheme: dark) {
    #view-logic .lg-head-float::before {
        background: linear-gradient(to bottom,
            var(--bg-main) 0%, var(--bg-main) 66%, rgba(24, 24, 27, 0) 100%);
    }
}
/* the lede is behind the ? on the board now — see boardBar(). Kept in the DOM for the
   screen readers and the translators; it costs two lines of the viewport on screen. */
.lg-lede { display: none; }
/* ── the tree ─────────────────────────────────────────────────────────────── */
.lg-tree { position: relative; }
/* DEPTH CARRIES THREE THINGS AT ONCE: indent (composition), type size (importance),
   and the colour tick (which side of the books). A reader gets the hierarchy from
   the shape before reading a single figure, and nothing needs a legend. */
/* `> .lg-card .lg-node` and never `.lg-branch .lg-node`: .lg-kids is a SIBLING of
   .lg-card, so this cannot reach into a child branch and give a depth-5 leg its
   grandparent's type size. */
.lg-branch[data-d="2"] > .lg-card .lg-label { font-size: 13.5px; }
.lg-branch[data-d="2"] > .lg-card .lg-value { font-size: 15px; }
.lg-branch[data-d="3"] > .lg-card .lg-label { font-size: 12.5px; }
.lg-branch[data-d="3"] > .lg-card .lg-value { font-size: 13.5px; }
.lg-branch[data-d="4"] > .lg-card .lg-label,
.lg-branch[data-d="5"] > .lg-card .lg-label { font-size: 12px; }
.lg-branch[data-d="4"] > .lg-card .lg-value,
.lg-branch[data-d="5"] > .lg-card .lg-value { font-size: 12.5px; }
/* ── THE ROOT IS A STATEMENT HEAD, NOT A BIGGER ROW ───────────────────────────
   The two roots are the only figures on this screen that exist to be COMPARED with each
   other, and they were the same drawing as an expense account one level down, two points
   larger. So they get the house's own headline setting instead — the name in small caps
   ABOVE the figure, the figure large, the caption under it — the way .kpi-value sets a
   total on Overview. (It also cited .lg-headline further down this file, which had not
   been emitted by anything for four versions and has since been deleted.)

   And the colour moves: a 4px tick down the left edge is a bullet, and a rule across the
   top edge is a heading. Full-bleed, so the card has to clip its own corners. */
.lg-branch[data-d="0"] > .lg-card .lg-node {
    grid-template-columns: 14px minmax(0, 1fr) 30px;
    grid-template-rows: 3px auto auto auto;
    row-gap: 2px; column-gap: 8px;
    padding: 0 18px 16px; overflow: hidden;
    /* THE RADIUS IS A SCALE, AND IT RAN BACKWARDS. The root sat at 18px while the
       account cards under it were 22 — the parent crisper than its own children, which
       reads as the small things being the important ones. Root 18 · card 16 · one-line
       leaf a true capsule, all on the house tokens. */
    border-radius: var(--radius-board);
}
/* `justify-self: stretch` is not decoration: .lg-node sets `justify-items: start`, so
   every grid item shrink-wraps its content — and an empty span's content is nothing. The
   bar was in the right cell, the right colour and the right height, and nought pixels
   wide. */
.lg-branch[data-d="0"] > .lg-card .lg-tick {
    grid-area: 1 / 1 / 2 / -1; align-self: start; justify-self: stretch;
    width: auto; height: 3px; min-height: 0; margin: 0 -18px 13px; border-radius: 0;
}
.lg-branch[data-d="0"] > .lg-card .lg-caret { grid-area: 2 / 1; align-self: center; }
/* `display: contents` so the label and the caption become grid items in their own right —
   the caption belongs UNDER the figure, and inside .lg-text it can only be above it */
.lg-branch[data-d="0"] > .lg-card .lg-text { display: contents; }
.lg-branch[data-d="0"] > .lg-card .lg-label {
    grid-area: 2 / 2; font-size: 11px; font-weight: var(--fw-semibold);
    letter-spacing: var(--tracking-caps); text-transform: uppercase; color: var(--text-muted);
}
.lg-branch[data-d="0"] > .lg-card .lg-value {
    grid-area: 3 / 2; font-size: 26px; letter-spacing: var(--tracking-tight); line-height: 1.15;
}
.lg-branch[data-d="0"] > .lg-card .lg-sub { grid-area: 4 / 2; font-size: 11px; }
/* a structural node is part of the diagram, not a control: no card, just the line */
.lg-node--static { background: transparent; border-color: transparent; }
.lg-node--static:hover { border-color: var(--divider); }
/* the operator rides ON the row it applies to, so the sign and the figure are read
   together — an operator on its own line is read as a heading */
.lg-sign {
    display: inline-block; min-width: 12px; margin-right: 4px;
    color: var(--text-muted); font-weight: var(--fw-semibold);
}
/* the one relationship that is an EQUALITY, not a composition */
.lg-eq {
    display: flex; align-items: center; gap: 8px;
    margin: 6px 0 6px 14px; padding: 4px 0;
    font-size: 11px; letter-spacing: var(--tracking-caps); text-transform: uppercase;
    color: var(--text-muted);
}
.lg-eq::before {
    content: ''; flex: 0 0 auto; width: 20px; height: 1.5px; background: var(--divider-strong);
}
.lg-eq--bad { color: var(--danger-red); }
.lg-eq--bad::before { background: var(--danger-red); }
/* ── THE CANVAS ───────────────────────────────────────────────────────────────
   A VIEWPORT ONTO SOMETHING LARGER, not a box the diagram has to fit inside.

   v13 cut the tree into vertical modules so it would fit the page, and every cut needed
   a caption and a wire to explain itself. This does not cut anything: depth goes right,
   siblings go down, and what does not fit is reached by moving the surface — dragged,
   scrolled or zoomed. The diagram is whatever size it turns out to be.

   THE LAYOUT IS ONE DECLARATION. `.lg-branch { display: flex }` puts a card on the left
   and its children in a column to the right, centred against it. Open a node and its
   subtree claims height, which grows its parent's row, which moves every sibling below —
   the "push the others aside" behaviour is the browser's own box model, which is why it
   lands in the same place every time. See js/views/logic.js for why that determinism
   ruled out a physics engine. */
/* NO PANEL. A border and a fill around the canvas drew a box the diagram was INSIDE,
   which is the opposite of what a board is: the surface is not a container, it is the
   page. Losing the frame also gives the tree the whole screen back — the border was
   costing two hairlines and the padding that had to sit inside them. What is left is the
   cards, their lines, and the paper. */
/* THE HEIGHT IS SET IN JS, from the canvas's own top to the bottom of the window — see
   fitBoard(). A clamp cannot do it: what sits above the board is a title, a period cluster
   that wraps on a narrow window and a lens switch that is two lines on a phone, and
   `calc(100vh - 190px)` was a guess at all three. Guessing left the tree in a short
   transparent window with the page scrolling behind it — two scrolls with different rules,
   and neither of them the board's. */
.lg-canvas {
    position: relative; overflow: auto;
    height: 70vh;                              /* replaced on the first frame by fitBoard */
    width: 100%; margin: 0; padding: 0;
    border: 0; background: transparent;
    overscroll-behavior: contain;
    cursor: grab;
    /* NO SCROLLBARS. A board is moved by dragging it, and a pair of bars down the edge of
       one is chrome describing a gesture nobody uses — it also shortened the canvas by
       their width and put a grey rule between the diagram and the screen. The surface is
       still scrollable by wheel, trackpad and keyboard; it just does not advertise it. */
    scrollbar-width: none;
    -ms-overflow-style: none;
}
.lg-canvas::-webkit-scrollbar { width: 0; height: 0; display: none; }
.lg-canvas.is-grabbing { cursor: grabbing; }
.lg-canvas.is-grabbing * { cursor: grabbing !important; }
.lg-stage {
    position: relative; transform-origin: 0 0;
    width: max-content; min-width: 100%;
    /* GENEROUS ON EVERY SIDE, because a board you cannot push past the last card is a
       board with edges. The right-hand allowance is the largest: it is where the next
       column opens into, and it should already be there when it does. */
    /* the top allowance clears the floating controls, so a card panned to the very top
       still lands below the title rather than behind it */
    padding: calc(var(--lg-head, 104px) + 24px) 40vw 120px var(--space-6);
}
/* roots stack; the tree inside each one grows sideways */
.lg-forest { display: flex; flex-direction: column; align-items: flex-start; gap: 22px; }
.lg-root { display: flex; }
/* the edges, under the cards — a line that crosses a card would be a line that lies
   about which cards it joins */
.lg-edges { position: absolute; left: 0; top: 0; pointer-events: none; z-index: 0; overflow: visible; }
/* THE EDGE MOVES WITH THE CARDS IT JOINS. `d` interpolates because every path here has
   the same command structure — M then one C — and because the elements are reused rather
   than rebuilt (see drawEdges). Same duration and curve as the FLIP, so the line and its
   two cards are one moving object instead of three that agree once it stops. */
.lg-edge {
    fill: none; stroke: var(--divider-strong); stroke-width: 1.5; stroke-linecap: round;
    transition: d .42s cubic-bezier(.34, 1.3, .48, 1), stroke .18s ease,
                stroke-width .18s ease, opacity .26s ease;
}
/* born at the parent's own point with no transition, so the growth it does on the next
   tick is a transition and not a jump */
.lg-edge--new { opacity: 0; transition: none; }
/* A CHILD OF NIL. Hairline and dashed: it is in the chart of accounts and not in the
   business, and drawing it at the same weight as a line carrying money would be the
   tree telling you they are the same kind of fact. */
.lg-edge--nil { stroke-dasharray: 3 4; opacity: .55; }
/* and a line whose child has gone retracts rather than vanishing */
.lg-edge--out { opacity: 0; transition: d .3s ease, opacity .3s ease; }

@media (prefers-reduced-motion: reduce) {
    .lg-edge, .lg-edge--out { transition: stroke .18s ease; }
}
/* ── THE TREE, SIDEWAYS ─────────────────────────────────────────────────────── */
/* CENTRED ON A SHORT LIST, TOP-ALIGNED ON A LONG ONE — decided from the measured height
   of the children's column by alignParents() in js/views/logic.js, because four children
   with open subtrees are taller than nine leaves and it is the height that decides
   whether centring strands the parent halfway down a screen of its own children. */
.lg-branch { position: relative; display: flex; align-items: center; z-index: 1; }
.lg-branch--top { align-items: flex-start; }
/* THE CARD IS A COLUMN NOW: the row itself, and the detail drawer under it. A drawer
   cannot live inside the card, because the card is a <button> and a panel of text inside
   a control is a panel you open by accident; and the tools cannot live inside it either,
   for the harder reason that a <button> inside a <button> is invalid markup and
   unreachable by keyboard. So the card holds the head, the head holds the row and its
   tools, and the drawer hangs below both. */
.lg-card { flex: 0 0 auto; display: flex; flex-direction: column; align-items: stretch; }
/* THE HEAD IS EXACTLY THE CARD. It used to be the card PLUS a tools column standing in
   the gutter, and the gutter is where the connectors run — see the port contract in
   js/views/logic.js. The tools are inside the card now, floated over a reserved grid
   column, so the head has no width of its own to contribute and the space between a card
   and its children is empty by construction. */
.lg-head { position: relative; display: block; }
/* ── ONE MODULE WIDTH, 320 ────────────────────────────────────────────────────
   Cards were 296 and the ledger boxes 320, so the column had two left edges agreeing
   and two right edges that did not — a grid with a 24px stagger in it is not a grid.
   320 is also what the one-line leaf needs to exist at all: at 296 the track left for a
   name, its code chip and its figure came to 155px against the 169 "Savings & Reserve
   Account" wants, so the leaf could be one line or it could be legible. It measured, and
   the width was the negotiable number. It also stopped "Main Operating Bank Account"
   truncating on the CARD, which it had been doing since before any of this. */
.lg-head > .lg-node { width: 320px; }
/* INSIDE THE CARD, ON THE RESERVED COLUMN. Absolute so it takes no part in the head's
   flow, over a 34px grid track .lg-node keeps clear, so text never runs beneath it and
   the children's x never depends on how many doors a row happens to have. */
.lg-tools {
    position: absolute; right: 9px; top: 50%; transform: translateY(-50%); z-index: 2;
    display: flex; flex-direction: column; align-items: center; gap: 2px;
}
.lg-branch > .lg-kids {
    display: flex; flex-direction: column; align-items: flex-start;
    margin: 0 0 0 88px; padding: 0;
}
.lg-kids[hidden] { display: none; }
.lg-kids > * { margin: 3px 0; }
/* the CSS spine and its elbows are gone: they could only reach a sibling, and the shape
   now reaches across a gap whose size changes. The edges are measured SVG — drawEdges(). */
.lg-kids::before { content: none; }
.lg-kids > .lg-branch > .lg-node::before,
.lg-kids > .lg-empty::before,
.lg-kids > .lg-more::before,
/* ── THE CONTROL AREA, DOCKED TO THE BOARD ────────────────────────────────────
   One bar, floating over the surface it acts on, grouped by the question each control
   answers: what period this is (left), and how much of the tree you can see (right).
   The explanation sits behind a ? because it is read once and then never again.
   The board is the positioning context; the canvas inside it is what scrolls. */
.lg-board {
    position: relative;
    width: 100vw; margin-left: calc(50% - 50vw);
    /* up under the floating controls — the band they used to occupy is board now */
    margin-top: calc(var(--lg-head, 104px) * -1);
}
.lg-bar {
    position: absolute; left: var(--space-6); right: var(--space-6); bottom: 12px; z-index: 4;
    display: flex; align-items: flex-end; gap: 12px;
    padding: 0 4px; pointer-events: none;      /* the board shows through between them */
}
.lg-bar > * { pointer-events: auto; }
.lg-bar-meta {
    display: flex; align-items: center; gap: 10px;
    padding: 7px 15px; border-radius: 999px;
    border: 1px solid var(--divider); background: var(--bg-card);
    box-shadow: 0 6px 18px -12px rgba(0,0,0,.35);
    font-size: 10.5px; letter-spacing: var(--tracking-caps); text-transform: uppercase;
    color: var(--text-muted);
}
.lg-bar-meta span + span::before { content: '·'; padding-right: 10px; color: var(--divider-strong); }
.lg-bar-tools { margin-left: auto; display: flex; align-items: center; gap: 8px; }
/* ── THE FLOATING MATERIAL ────────────────────────────────────────────────────
   The controls sit ON the board, so they are made of the surface rather than dropped on
   it: a translucent fill with the diagram blurred behind, which is the one iOS idea that
   is actually about depth rather than decoration — it says "this is nearer you" without
   drawing a single extra line. Falls back to the solid card colour where backdrop-filter
   is not supported, which is the same control one layer flatter and loses nothing. */
.lg-bar-meta, .lg-help, .lg-struct, .lg-zoom, .lg-note, .lg-md {
    background: color-mix(in srgb, var(--bg-card) 82%, transparent);
    backdrop-filter: saturate(180%) blur(20px);
    -webkit-backdrop-filter: saturate(180%) blur(20px);
}
@supports not (backdrop-filter: blur(1px)) {
    .lg-bar-meta, .lg-help, .lg-struct, .lg-zoom, .lg-note, .lg-md { background: var(--bg-card); }
}
.lg-help, .lg-struct {
    display: grid; place-items: center; width: 32px; height: 32px;
    border: 1px solid var(--divider); border-radius: 999px;
    box-shadow: 0 6px 18px -12px rgba(0,0,0,.35);
    font: inherit; font-size: 13px; color: var(--text-muted); cursor: pointer;
    transition: color .15s ease, border-color .15s ease, transform .22s cubic-bezier(.32,.72,0,1);
}
.lg-struct .material-icons-outlined { font-size: 16px; }
.lg-help:hover, .lg-help[aria-expanded="true"],
.lg-struct:hover, .lg-struct[aria-expanded="true"] { color: var(--text-main); border-color: var(--text-main); }
.lg-struct[aria-expanded="true"] { transform: scale(1.06); }
/* ── THE TREE, AS A DOCUMENT ──────────────────────────────────────────────────
   Monospaced, because it is a file and not prose, and scrollable inside its own panel so
   a long chart of accounts does not push the board around. */
.lg-md {
    position: absolute; right: 4px; bottom: 46px; z-index: 5;
    display: flex; flex-direction: column;
    width: min(520px, calc(100% - 8px)); max-height: min(60vh, 520px);
    border: 1px solid var(--divider); border-radius: var(--radius-board);
    box-shadow: 0 20px 50px -22px rgba(0,0,0,.5);
    overflow: hidden;
}
.lg-md[hidden] { display: none; }
.lg-md-head {
    display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
    padding: 11px 15px; border-bottom: 1px solid var(--divider);
}
.lg-md-what {
    font-size: 11px; font-weight: var(--fw-semibold); color: var(--text-main);
    letter-spacing: var(--tracking-wide);
}
.lg-md-cost { font-size: 10px; letter-spacing: var(--tracking-caps); text-transform: uppercase; color: var(--text-muted); }
.lg-md-body {
    flex: 1 1 auto; min-height: 0; overflow: auto; margin: 0; padding: 13px 15px;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 11px; line-height: 1.62; color: var(--text-main);
    white-space: pre; tab-size: 2;
}
.lg-md-acts { display: flex; gap: 8px; padding: 10px 15px 0; }
.lg-md-acts button {
    padding: 7px 14px; border: 1px solid var(--divider); border-radius: 999px;
    background: transparent; font: inherit; font-size: 10.5px;
    letter-spacing: var(--tracking-caps); text-transform: uppercase;
    color: var(--text-main); cursor: pointer; transition: border-color .16s ease;
}
.lg-md-acts button:hover { border-color: var(--text-main); }
.lg-md-note {
    margin: 0; padding: 10px 15px 13px;
    font-size: 10px; line-height: var(--leading-relaxed); color: var(--text-muted);
}
.lg-zoom {
    display: flex; align-items: center; gap: 2px; padding: 3px;
    border: 1px solid var(--divider); border-radius: 999px;
    background: var(--bg-card); box-shadow: 0 6px 18px -12px rgba(0,0,0,.35);
}
.lg-zoom button {
    display: grid; place-items: center; min-width: 30px; height: 26px;
    border: 0; border-radius: 999px; background: transparent;
    font: inherit; font-size: 13px; line-height: 1; color: var(--text-muted); cursor: pointer;
    transition: background .15s ease, color .15s ease;
}
.lg-zoom button:hover { background: var(--active-theme-bg); color: var(--text-main); }
.lg-zoom .material-icons-outlined { font-size: 16px; }
.lg-zoom-sep { width: 1px; height: 16px; margin: 0 3px; background: var(--divider); }
.lg-zoom .lg-zoom-pct {
    min-width: 44px; text-align: center; font-size: 11px;
    letter-spacing: var(--tracking-caps); color: var(--text-main);
}
/* the explanation, on demand */
.lg-note {
    position: absolute; right: 4px; bottom: 46px; z-index: 5;
    width: min(360px, calc(100% - 8px)); margin: 0; padding: 13px 16px;
    border: 1px solid var(--divider); border-radius: var(--radius-board);
    background: var(--bg-card); box-shadow: 0 16px 40px -20px rgba(0,0,0,.45);
    font-size: 12px; line-height: var(--leading-relaxed); color: var(--text-muted);
}
.lg-note[hidden] { display: none; }
/* THE = SITS ON THE ROOTS' OWN LINE, and it is a TRACK, not a margin — a 92px column of
   the grid, so it stays between the two roots however many modules open to their right.
   Both roots open with a d=0 card, so the mark is nudged down by half that card's height:
   anywhere else and it points at the gap between two rows instead of at the two figures
   it is about. The condition is the sheet's own measurement, not a media query — the
   stacked rule and the column mark are two states of one control, and only the engine
   knows which one is in force. */
.lg-forest > .lg-eqv {
    display: inline-flex; align-items: center; gap: 10px;
    width: max-content; margin: 0 0 0 6px; padding: 5px 16px 5px 6px;
    border: 1px solid var(--divider); border-radius: 999px; background: var(--bg-card);
}
.lg-forest > .lg-eqv::before { display: none; }
.lg-eqv-sign {
    display: grid; place-items: center; width: 32px; height: 32px; border-radius: 999px;
    border: 1.5px solid var(--divider-strong); background: var(--bg-card);
    font-size: 15px; line-height: 1; color: var(--text-main);
}
.lg-eqv-tag { line-height: 1.3; }
.lg-eqv--bad .lg-eqv-sign { border-color: var(--danger-red); color: var(--danger-red); }
/* A BRANCH IS A FLEX ROW: the card, the record mark, then the children's column. It was
   a two-column grid while the tree ran downwards — right then, and fatal now: this rule
   sits LATER in the file than the one that makes the tree horizontal, so `display: grid`
   quietly won and the tree came out vertical. Every measurement said so; it took reading
   the cascade to see why.

   THE TOOLS' SLOT IS A CONSTANT, NOT A TRACK. Cards are all CARD_W wide, so their right
   edges align by construction, and .lg-tools is a fixed 30px whether it holds two doors,
   one or none — so the children's column sits at the same x on every row. */
/* the doors on a row. Quiet by default — they are second actions on a row whose first
   action is the point — and they come forward on hover and on keyboard focus. */
/* ONE DOOR PER ROW, AND IT KEEPS ITS DISTANCE UNTIL ASKED. Two glyphs on every card of
   a dense diagram is a diagram of glyphs; at .28 it is a mark you can see is there and
   not a thing you have to read past. It comes fully forward on hover and on keyboard
   focus — and stays forward where there is no hover at all, because on a touch screen a
   control that only appears on hover is a control that does not exist. */
.lg-insp, .lg-drop {
    display: grid; place-items: center; flex: 0 0 auto;
    width: 26px; height: 24px;
    border: 0; border-radius: 999px; background: transparent;
    color: var(--text-muted); opacity: .78; cursor: pointer;
    transition: opacity .16s ease, background .16s ease, color .16s ease, transform .22s cubic-bezier(.32,.72,0,1);
}
@media (hover: hover) {
    .lg-insp, .lg-drop { opacity: .28; }
}
.lg-insp .material-icons-outlined, .lg-drop .material-icons-outlined { font-size: 15px; }
.lg-insp:hover, .lg-insp:focus-visible,
.lg-drop:hover, .lg-drop:focus-visible { opacity: 1; color: var(--text-main); background: var(--active-theme-bg); }
.lg-branch:hover > .lg-card .lg-insp,
.lg-branch:hover > .lg-card .lg-drop,
.lg-card:focus-within .lg-insp,
.lg-card:focus-within .lg-drop { opacity: 1; }
/* the detail door turns over when its drawer is open, like the caret does when a branch
   is — one gesture vocabulary for two axes */
.lg-drop[aria-expanded="true"] { opacity: 1; color: var(--text-main); transform: rotate(180deg); }
/* the end of the trace: the row itself opens the record, so it reads as a target */
.lg-node--rec { cursor: pointer; }
.lg-node--rec:hover { background: var(--active-theme-bg); }
/* ── ONE CARD: caret · colour bar · name over figure, all flush left ───────────
   IT WAS A ROW — caret, tick, name, figure, on one line — and a row is right when rows
   are stacked and their figures line up down a column. Sideways they do not: a card is
   296px wide whatever is in it, so name and figure fought over the same line and both
   lost. "Main Operating Account · HKD 816,110.38" came out "Main Operatin…".

   So the figure moves under the name and everything is set flush left against one edge.
   Siblings still stack vertically, so their figures still align down a column — the
   comparison survives, and the name gets the whole width. */
/* ONE TEXT AXIS, AND IT IS THE WHOLE FIX. The caret gutter is 12, the rule is 3, the
   gaps are 10 and the inset is 16 — so every label on this screen begins at 51px from
   its card's left edge, card or leaf, at every depth. A leaf used to drop the caret
   column and thin the rule, which moved its text 44px left of its siblings': a column
   that was not a column. The caret is HIDDEN on a leaf, never removed. */
.lg-node {
    display: grid;
    grid-template-columns: 12px 3px minmax(0, 1fr) 30px;
    grid-template-rows: auto auto;
    column-gap: 10px; row-gap: 4px;
    align-items: center; justify-items: start; text-align: left; width: 100%;
    padding: 13px 16px; margin: 2px 0;
    border: 1px solid var(--divider); border-radius: var(--radius-lg);
    background: var(--bg-card); text-align: left; font: inherit; color: inherit;
    cursor: pointer;
    transition: border-color .18s ease, background .18s ease, transform .18s cubic-bezier(.32,.72,0,1);
}
.lg-node:hover:not([disabled]) { border-color: var(--divider-strong); }
.lg-node:active:not([disabled]) { transform: scale(0.99); }
/* ── LEAVES, AND THE ONE THAT IS A PILL ───────────────────────────────────────
   A leaf opens nothing. It used to be a capsule wrapped around a THREE-LINE block —
   name, code, figure — and that is a shape describing something it was not: a 999px
   radius on a 168px-tall box spends eighty of its pixels on two lobes that can hold no
   text, sets straight-ended rules inside a curve, and leaves the name less room than the
   card above it. It looked broken because it was. The form said "one short thing" and
   the contents were three.

   TWO STATES NOW, AND THE DATA PICKS. A leaf whose figure is a MARK — a nil account's
   "—" — really is one line, so it is a real capsule at 49px tall, name and code chip and
   dash, left to right. A leaf whose figure is a NUMBER keeps the card's two rows and is
   made quiet by ink and fill instead. See cardHtml() in js/views/logic.js.

   THE COLUMNS ARE THE CARD'S EITHER WAY. Same caret gutter, same 3px rule, same 16px
   inset — every label on this screen starts 52px from its card's left edge, at every
   depth, in every state. The caret is HIDDEN on a leaf, never removed: removing it is
   what used to move the text 44px left of its siblings' and make the column a zigzag. */
.lg-node--leaf {
    cursor: default;
    background: var(--bg-main); border-color: var(--divider);
}
.lg-node--leaf .lg-caret { visibility: hidden; }
/* ── the capsule ─────────────────────────────────────────────────────────── */
.lg-node--pill {
    padding: 12px 16px; border-radius: 999px;
    grid-template-columns: 12px 3px minmax(0, 1fr) auto 30px;
    grid-template-rows: auto;
    column-gap: 10px; row-gap: 0;
}
.lg-node--pill .lg-tick  { grid-area: 1 / 2; height: 15px; min-height: 0; align-self: center; }
.lg-node--pill .lg-text  {
    grid-area: 1 / 3; flex-direction: row; align-items: baseline; gap: 6px; min-width: 0;
}
/* one point down, and it is not a whim: at 13.5px the longest names in a real chart —
   "Computer & Office Equipment", "Grant Receivable — Cyberport" — overrun the single
   line by a few pixels and ellipsis a word for nothing. */
.lg-node--pill .lg-label { flex: 0 1 auto; min-width: 0; font-size: 12px; }
.lg-node--pill .lg-sub   { flex: 0 0 auto; }
/* the chip's trailing margin is a gap before text that is not there on one line, and
   caps tracking on a four-digit code buys nothing but the four pixels that were still
   clipping "Computer & Office Equipment" */
.lg-node--pill .lg-code  { margin-right: 0; padding: 0 4px; letter-spacing: 0; }
.lg-node--pill .lg-value { grid-area: 1 / 4; justify-self: end; }
/* a leaf that opens a record is a pill you can press */
.lg-node--rec { cursor: pointer; }
.lg-node--rec:hover { border-color: var(--divider-strong); background: var(--active-theme-bg); }

/* ── THE ACCOUNT CODE, AS THE CHIP IT ALREADY IS ELSEWHERE ────────────────────
   1010 was a bare number in this screen's sub-line and a bordered chip on the chart of
   accounts, six pixels tall and one screen away: the same fact, drawn twice, in one app.
   This is .acc-code from accounts.css at the tree's scale — the code is an IDENTIFIER,
   not prose, and a chip is how this product says so. */
.lg-code {
    display: inline-block; margin-right: 7px; padding: 0 5px;
    border: 1px solid var(--divider-strong); border-radius: 4px;
    background: var(--bg-main);
    font-size: 9.5px; font-weight: var(--fw-semibold); line-height: 1.6;
    color: var(--text-muted); font-variant-numeric: tabular-nums;
    letter-spacing: var(--tracking-caps); vertical-align: 1px;
}
/* ── DOWN: WHAT THIS LINE IS ──────────────────────────────────────────────────
   The drawer continues the card rather than floating under it, so the card squares its
   own bottom corners while it is open — one object that grew, not two that touch. */
.lg-card:has(> .lg-drawer:not([hidden])) .lg-node {
    border-bottom-left-radius: 5px; border-bottom-right-radius: 5px;
}
.lg-drawer {
    width: 320px; margin: -1px 0 2px; padding: 4px 16px 12px;
    border: 1px solid var(--divider); border-top: 0;
    border-radius: 0 0 var(--radius-lg) var(--radius-lg); background: var(--bg-main);
}
.lg-drow {
    display: flex; align-items: baseline; justify-content: space-between; gap: 14px;
    padding: 6px 0; border-bottom: 1px solid var(--divider);
}
.lg-drow:last-child { border-bottom: 0; }
.lg-dk { font-size: 10.5px; color: var(--text-muted); }
.lg-dv { font-size: 11.5px; color: var(--text-main); white-space: nowrap; }
.lg-drow.is-strong .lg-dv { font-weight: var(--fw-semibold); }
.lg-dnote {
    margin: 9px 0 0; font-size: 10.5px; line-height: var(--leading-relaxed);
    color: var(--text-muted);
}
/* THE WAY OUT OF THE DRAWER, and the second half of the grouping: the record door used to
   be a bare icon beside the card, telling the reader nothing about where it went. Here it
   is a labelled row at the end of the facts, which is exactly when someone wants it. */
.lg-dgo {
    display: flex; align-items: center; justify-content: space-between; gap: 10px;
    width: 100%; margin: 10px 0 0; padding: 9px 12px;
    border: 1px solid var(--divider); border-radius: 999px; background: var(--bg-card);
    font: inherit; font-size: 10.5px; letter-spacing: var(--tracking-caps);
    text-transform: uppercase; color: var(--text-main); cursor: pointer;
    transition: border-color .16s ease, background .16s ease;
}
.lg-dgo:hover { border-color: var(--text-main); background: var(--active-theme-bg); }
.lg-dgo .material-icons-outlined { font-size: 15px; color: var(--text-muted); }
/* ── THE END OF A TRACE: A RECORD, RULED ──────────────────────────────────────
   The house's own .acc-group, at the tree's scale: a recessed box, a heading bar, and
   hairline-ruled rows. A batch is one journal entry and its legs are its lines; a
   project's result is a two-line P&L with the margin as its foot; a role's powers are a
   list whose heading is the role. None of those is a set of cards, and drawing them as
   cards promised the reader something to open that was never there.

   THE FOOT IS WHY THE BOX EXISTS. A batch's ✓ debits = credits is the invariant these
   books are built on, and it used to float beside the legs as a seventh pill; a
   project's margin is the only figure anybody opened the project for. A total belongs
   under a rule, at the bottom of the thing it totals. */
.lg-ledger {
    width: 320px; margin: 3px 0;
    border: 1px solid var(--divider); border-radius: var(--radius-board);
    background: var(--bg-card); overflow: hidden;
    transition: border-color .18s ease;
}
.lg-lcap {
    display: flex; align-items: center; gap: 10px;
    padding: 9px 14px; border-bottom: 1px solid var(--divider);
    background: var(--active-theme-bg);
}
/* THE NARRATION OUTRANKS THE DATE, so they stack rather than compete for one line. Side
   by side, "2029-03-30 · PAY-202903" is fixed-width and wins by construction, and a
   perfectly legible reference sat next to "Salary Mar 20…" — the one part of the heading
   nobody can reconstruct from anywhere else on the screen. */
.lg-ltx { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.lg-lwhat {
    min-width: 0; font-size: 11px; font-weight: var(--fw-semibold); color: var(--text-main);
    letter-spacing: var(--tracking-wide);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.lg-lwhen {
    font-size: 9.5px; letter-spacing: var(--tracking-caps); text-transform: uppercase;
    color: var(--text-muted); font-variant-numeric: tabular-nums;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.lg-lcap .lg-insp { flex: 0 0 auto; margin-left: auto; }
.lg-lrows { display: flex; flex-direction: column; }
.lg-lrow {
    display: grid; grid-template-columns: 3px minmax(0, 1fr) auto;
    align-items: center; column-gap: 10px;
    padding: 8px 14px; border-bottom: 1px solid var(--divider);
    transition: background .16s ease;
}
.lg-lrow:last-child { border-bottom: 0; }
.lg-lrow:hover { background: var(--bg-hover); }
.lg-ltick { width: 3px; min-height: 16px; border-radius: 2px; align-self: stretch; }
.lg-lname {
    display: flex; flex-direction: column; gap: 1px; min-width: 0;
    font-size: 11.5px; color: var(--text-main);
    overflow: hidden; text-overflow: ellipsis;
}
.lg-lsub {
    font-size: 9.5px; color: var(--text-muted);
    letter-spacing: var(--tracking-caps); text-transform: uppercase;
}
.lg-lval {
    font-size: 12px; color: var(--text-main);
    white-space: nowrap; letter-spacing: var(--tracking-tight);
}
.lg-lrow.is-muted .lg-lname, .lg-lrow.is-muted .lg-lval { color: var(--text-muted); }
.lg-lrow.is-strong .lg-lval { font-weight: var(--fw-semibold); }
.lg-lfoot {
    display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
    padding: 10px 14px; border-top: 1px solid var(--divider-strong);
    background: var(--bg-main);
    font-size: 10px; letter-spacing: var(--tracking-caps); text-transform: uppercase;
    color: var(--text-muted);
}
.lg-lfval {
    font-size: 13px; font-weight: var(--fw-semibold); color: var(--text-main);
    text-transform: none; letter-spacing: var(--tracking-tight);
}
.lg-lfoot.is-bad, .lg-lfoot.is-bad .lg-lfval { color: var(--danger-red); }
/* the access control and the list it governs are ONE child of the tree, so one edge
   arrives at them rather than two at two halves of the same answer */
.lg-access { display: flex; flex-direction: column; width: 320px; }
/* ── LIT: THE LINEAGE OF WHATEVER THE CURSOR IS ON ────────────────────────────
   Additive, never subtractive. Dimming everything else would read the path faster and
   would also, on a screen whose subject is that the two sides must agree, hide the half
   of the statement the reader is not touching. */
/* ONE WEIGHT ACROSS THE WHOLE LIT PATH. The cable was 2.2 and the card it ran into was
   a 1px border, so the highlight changed thickness at every card — it read as two
   different marks that happened to meet. Both are 2px now: the ring is a box-shadow
   rather than a thicker border because growing a border grows the box, which moves the
   card, which moves the very edge being drawn. */
.lg-node.is-lit:not([disabled]), .lg-ledger.is-lit {
    border-color: var(--text-main);
    box-shadow: 0 0 0 1px var(--text-main);
}
.lg-edge--lit { stroke: var(--text-main); stroke-width: 2; }
/* the small print of the tree, all pills: nothing here is a row in a table any more */
.lg-empty, .lg-more {
    display: inline-block; width: auto; margin: 3px 0;
    padding: 7px 16px; border-radius: 999px;
    border: 1px solid var(--divider); background: var(--bg-card);
}
.lg-more { cursor: pointer; }
.lg-more:hover { border-color: var(--divider-strong); }
.lg-caret {
    grid-area: 1 / 1; width: 12px; text-align: center;
    font-size: 15px; line-height: 1; color: var(--text-muted);
    transition: transform .22s cubic-bezier(.32,.72,0,1);
}
.lg-node[aria-expanded="true"] .lg-caret { transform: rotate(90deg); color: var(--text-main); }
/* the colour bar runs the full height of the card now, so it reads as the card's own
   edge rather than a bullet beside a line */
/* 3px and fully rounded: a RULE beside the text, not a bar bolted to the card. The
   width is load-bearing — it is one of the four numbers that put every label on this
   screen at the same x (see .lg-node).

   AND IT CARRIES HOW BUSY THE ACCOUNT IS. --lg-act is the account's movement in the
   period against the busiest in its own section (see scaleChurn in js/views/logic.js),
   and it rides on the rule's OPACITY — no new element, no space taken, and it scans
   down a column in one look: a full tick is where the work is happening, a faint one is
   an account that is merely large. The bank account is 92% of the assets and carries
   almost all the movement; receivables are a twentieth of them and turn over constantly.
   Neither of those facts is in a balance. Accounts only — a section head or a project
   has no debit side, and inventing one would be the screen making it up. */
.lg-tick {
    grid-area: 1 / 2 / span 2 / auto; width: 3px; height: 100%; min-height: 20px;
    border-radius: 999px; align-self: stretch;
    opacity: calc(0.34 + 0.66 * var(--lg-act, 1));
    transition: opacity .22s ease;
}
.lg-text { grid-area: 1 / 3; min-width: 0; width: 100%; display: flex; flex-direction: column; gap: 2px; }
.lg-label {
    font-size: 13px; color: var(--text-main);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.lg-sub {
    font-size: 10.5px; color: var(--text-muted);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.lg-value {
    grid-area: 2 / 3 / 3 / -1; font-size: 15px; font-weight: var(--fw-semibold); color: var(--text-main);
    white-space: nowrap; letter-spacing: var(--tracking-tight);
}
.lg-node--leaf .lg-label,
.lg-node--leaf .lg-value { color: var(--text-muted); font-weight: var(--fw-regular); }
/* THE VERTICAL TREE'S CONNECTORS ARE GONE, NOT OVERRIDDEN.
   A spine down each branch and a rounded elbow per child — correct for a tree that ran
   downwards, and the wrong drawing entirely for one that runs across. They were
   neutralised with `content: none` further up this file and it did nothing, because
   these rules sat BELOW that and won: the screen carried both drawings at once, the
   measured curves and a scatter of orphaned elbows the curves did not explain. Deleted
   rather than switched off, so the next person does not find a disabled second answer.
   The edges are drawn by drawEdges() in js/views/logic.js. */
.lg-kids[hidden] { display: none; }

/* ── ACCESS, AS A CONTROL ─────────────────────────────────────────────────────
   Two options, one gate. They are drawn as check rows rather than a switch because the
   list of powers underneath is the real subject: the reader is choosing which of those
   lists applies, not flipping a preference. See fillPerson in js/views/logic.js for why
   there are two of these and not thirteen. */
.lg-perm { margin: 4px 0 10px; }
.lg-perm-h {
    font-size: 10.5px; letter-spacing: var(--tracking-caps); text-transform: uppercase;
    color: var(--text-muted); padding: 2px 0 8px 2px;
}
.lg-perm-opts { display: grid; gap: 6px; }
.lg-perm-opt {
    display: flex; align-items: flex-start; gap: 10px; width: 100%; text-align: left;
    padding: 10px 12px; border: 1px solid var(--divider); border-radius: var(--radius-sm);
    background: var(--bg-card); font: inherit; color: inherit; cursor: pointer;
    transition: border-color .18s ease, background .18s ease;
}
.lg-perm-opt:hover:not([disabled]) { border-color: var(--divider-strong); }
.lg-perm-opt[disabled] { cursor: default; opacity: .62; }
.lg-perm-opt.is-on { border-color: var(--text-main); }
.lg-perm-box {
    flex: 0 0 auto; display: grid; place-items: center;
    width: 17px; height: 17px; margin-top: 1px; border-radius: 5px;
    border: 1.5px solid var(--divider-strong); background: var(--bg-card);
    font-size: 11px; line-height: 1; color: var(--text-main);
}
.lg-perm-opt.is-on .lg-perm-box { background: var(--text-main); border-color: var(--text-main); color: var(--bg-card); }
.lg-perm-tx { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.lg-perm-tx b { font-size: 12.5px; font-weight: var(--fw-semibold); color: var(--text-main); }
.lg-perm-tx span { font-size: 10.5px; line-height: var(--leading-relaxed); color: var(--text-muted); }
.lg-perm-note, .lg-perm-msg {
    font-size: 10.5px; line-height: var(--leading-relaxed); color: var(--text-muted);
    margin: 8px 0 0; padding: 0 2px;
}
.lg-perm-msg:empty { display: none; }
.lg-perm-msg { color: var(--danger-red); }
/* .lg-op, .lg-op-sign, .lg-identity, .lg-headline* LIVED HERE AND ARE GONE. They were
   the operator rows, the A = L + E verdict and the headline block of v9 through v12, and
   nothing has emitted any of them for several versions — including, embarrassingly, the
   .lg-headline this file cited as the precedent for the root card's setting. Dead CSS is
   worse than no CSS: it reads as a decision somebody made about the screen in front of
   you. The period label they sat with is now .lg-bar-meta, docked to the board. */
.lg-empty {
    font-size: 11px; letter-spacing: var(--tracking-caps); text-transform: uppercase;
    color: var(--text-muted); padding: 10px 12px;
}
/* TYPE ONLY. This rule used to set `display: block; width: 100%; border: 0; background:
   transparent` as well — the vertical tree's full-width row — which sits BELOW the pill
   rule and quietly unmade it: "more · 56" rendered as bare left-aligned text with a
   999px radius on nothing. The box belongs to the pill; this says how it reads. */
.lg-more {
    font: inherit; font-size: 10.5px; letter-spacing: var(--tracking-caps);
    text-transform: uppercase; color: var(--text-muted); cursor: pointer;
}
.lg-more:hover { color: var(--text-main); border-color: var(--divider-strong); }
/* THE INDENT IS GONE, AND SO IS THE MEDIA QUERY THAT TUNED IT. Depth used to cost
   horizontal margin, so every width needed its own step; depth is now a column of its
   own on a surface that scrolls, and a column costs the same at every width. */
@media (min-width: 760px) {
    .lg-node { padding: 13px 16px; }
    .lg-label { font-size: 13.5px; }
    .lg-value { font-size: 14px; }
}
/* THE ARRIVAL ANIMATION LIVED HERE and is deliberately gone. It lifted each new row 4px
   and settled it — right for the vertical tree it was written for, and one animation too
   many now that FLIP animates arrival from the card that opened. Running both moved the
   rows AFTER drawEdges had measured them, so every edge into a freshly opened list came
   out exactly 4px short. See toggle() in js/views/logic.js. */
.lg-caret { transition: transform .24s cubic-bezier(.32, .72, 0, 1), color .18s ease; }
@media (prefers-reduced-motion: reduce) { .lg-caret { transition: none; } }

/* ── THE DOCUMENT, IN THE TREE ────────────────────────────────────────────────
   A4 is 210mm — about 794px — and the tree's cards are 296. So the page is drawn at full
   size and SCALED DOWN into a frame, rather than re-laid-out smaller: the same builder
   the Documents screen uses, at the same proportions, so what hangs off the project is
   the document and not a second drawing of it that could disagree.

   IT IS A THUMBNAIL AND SAYS SO. The frame is fixed and clips — you get the head of the
   page, which is where the reference, the date, the client and the total live. Reading
   the whole thing is what the Documents screen is for, and the caption links there. */
.lg-paper {
    display: inline-block; margin: 4px 0;
    border: 1px solid var(--divider); border-radius: var(--radius-sm);
    background: var(--bg-card); overflow: hidden;
}
.lg-paper-cap {
    display: flex; align-items: center; gap: 14px;
    padding: 9px 14px; border-bottom: 1px solid var(--divider);
    font-size: 10.5px; letter-spacing: var(--tracking-caps); text-transform: uppercase;
    color: var(--text-muted);
}
.lg-paper-go {
    margin-left: auto; padding: 4px 12px; border-radius: 999px;
    border: 1px solid var(--divider); background: transparent;
    font: inherit; font-size: 10px; letter-spacing: var(--tracking-caps);
    text-transform: uppercase; color: var(--text-main); cursor: pointer;
    transition: border-color .16s ease;
}
.lg-paper-go:hover { border-color: var(--text-main); }
/* 420 / 794 ≈ 0.529 — the frame's width divided by A4's, so the page lands exactly in it */
.lg-paper-frame { width: 420px; height: 560px; overflow: hidden; background: #fff; }
.lg-paper-page { transform: scale(0.529); transform-origin: top left; width: 794px; }
/* the page is white paper whatever the app's theme is — an invoice is not themed */
.lg-paper-page .a4-preview-doc { box-shadow: none; }

/* ── THE PHONE ────────────────────────────────────────────────────────────────
   A horizontal tree on a 375px screen is still a lot of panning, and this does not
   pretend otherwise. What it does fix is the two things that made it worse than it had
   to be: cards sized for a desktop column, and a canvas that pulled itself wider than
   the screen.

   THE SHELL INSETS 16px HERE, NOT 24. `.lg-canvas` pulled out by --space-6 to reach the
   page's own edges — right on a desktop, and 8px too far on a phone, which put a
   HORIZONTAL SCROLLBAR ON THE WHOLE PAGE. On a phone a sideways drag is how you leave a
   screen, so the diagram's own gesture and the page's were fighting over the same eight
   pixels. */
@media (max-width: 759px) {
    .lg-canvas {
        margin: 0 -16px; padding: 0 16px;
        height: clamp(440px, calc(100vh - 240px), 900px);
    }
    .lg-stage { padding: 40px 60vw 80px 8px; }
    .lg-head > .lg-node, .lg-drawer { width: 252px; }
    .lg-ledger, .lg-access { width: 252px; }
    .lg-branch > .lg-kids { margin-left: 48px; }
    .lg-branch[data-d="0"] > .lg-card .lg-value { font-size: 21px; }
    .lg-paper-frame { width: 232px; height: 320px; }
    .lg-paper-page { transform: scale(0.292); }
    /* the bar goes to the controls only. The period is already the Month/Year cluster
       directly above the board on a phone, and a second copy of it wrapped onto two lines
       and ran into the ? beside it — the same fact, twice, in the space of one. */
    .lg-bar-meta { display: none; }
    .lg-bar { bottom: 8px; padding: 0 2px; }
    .lg-note { right: 2px; bottom: 44px; }
}


