/* studio surface styles — Jessica's. Slice 1 placeholder: enough to read the
   page and the styleguide, nothing more. */
body.studio { margin: 0; font-family: var(--font-ui); color: var(--color-ink); background: var(--color-paper); }
body.studio:not(.framed) main { max-width: 48rem; margin: 0 auto; padding: var(--space); }
/* Slice 7: signed-in pages live in THE FRAME (below); pages not yet restyled
   sit in this plain column inside it — FLAGGED for Jessica, not restyled by
   stealth. The styleguide's foundation samples need the full width.
   Sep 3: the wrapper adopts the frame's CONTENT COLUMN instead of its own —
   the same negative-margin/--content-edge move as .sec, so a list page's
   first text and Home's h1 share one x; content-box so --content (944) is
   the text's ceiling, the edges outside it; type inherited (body.framed's
   base type), not the legacy --font-ui. What's INSIDE stays as built — the
   rows, tables, and links await their sitting. */
.frame .legacy { box-sizing: content-box; max-width: var(--content); margin: 0 calc(-1 * var(--gx)); padding: calc(4 * var(--u)) var(--content-edge) calc(6 * var(--u)); }   /* .frame-qualified: the frame's universal border-box would otherwise win the tie and eat the edges out of the 944 */
.legacy:has(.styleguide-intro) { max-width: none; }
.legacy-foot { margin-top: calc(6 * var(--u)); font-size: 0.85rem; }
html:has(body.framed){background:var(--outside)}   /* the ground outside the frame, past ~1300 — on the morning's list since Aug 31, landed with the panel */
html { scrollbar-gutter: stable; }   /* the frame doesn't shift when the scrollbar appears (Sep 3): measured .frame at x = 2 on Home (scrolls) and x = 9 on Clients (doesn't), a 7px jump on every tab change; the gutter is reserved whether or not the page scrolls. Pinned here, not in PHPUnit — a test that the frame's left is identical on a scrolling and a non-scrolling page isn't cheap there, so this measurement is the pin */
body.framed { background: var(--outside); margin: 0; font: 400 15px/1.5 var(--ui); }   /* the foundation's base type (spec) — body.studio's Circular is the LEGACY stand-in layer and stays for unstyled slice-1 pages */
body.studio:not(.framed) header, body.studio:not(.framed) footer { padding: var(--space); display: flex; gap: var(--space); align-items: baseline; }   /* legacy stand-in pages only — the frame's masthead and footer are <header>/<footer> too (Sep 3) and were catching this padding */
body.studio:not(.framed) nav a { margin-right: var(--space); }   /* legacy stand-in pages only — this was reaching the frame's rail and insetting every cell's line 16px short of the canvas (Aug 31) */
.field { margin-bottom: var(--space); }
.field label { display: block; margin-bottom: 0.25rem; }
.field--error input { outline: 2px solid var(--color-error); }
.field-error { color: var(--color-error); margin: 0.25rem 0 0; }
.flash { padding: 0.75rem var(--space); margin-bottom: var(--space); background: var(--highlight); }   /* the studio's HIGHLIGHT, not the legacy accent (Chris, Sep 5): one yellow — the active nav cell, field focus, and the flash say "here" in the same voice */
.flash--error { background: var(--color-error); color: white; }
.styleguide-component { border-top: 1px solid var(--color-ink); padding-top: var(--space); }
.styleguide-sample { padding: var(--space); border: 1px dashed #ccc; }
.error-trace { overflow-x: auto; font-size: 0.8rem; }

/* Slice 3 placeholders — Jessica's to replace: pickers, asset slots. (The
   slice-3 nav/sub-nav stand-ins retired in slice 7: the frame's rail and the
   bar's tabs are the nav now.) */
.field--checkbox label { display: inline-flex; gap: 0.5rem; align-items: center; }
.field-hint { margin: 0.25rem 0 0; font-size: 0.85rem; opacity: 0.75; }
.swatches, .font-sets { border: 0; padding: 0; margin: 0 0 var(--space); }
.swatches legend, .font-sets legend { margin-bottom: 0.5rem; }
.swatch { display: inline-flex; align-items: center; gap: 0.35rem; margin: 0 0.75rem 0.5rem 0; cursor: pointer; }
.swatch-color { display: inline-block; width: 1.5rem; height: 1.5rem; border-radius: 50%; border: 1px solid rgba(0,0,0,0.15); }
.swatch input:checked + .swatch-color { outline: 2px solid var(--color-ink); outline-offset: 2px; }
.swatches-custom { font-size: 0.85rem; }
.font-set { display: block; margin-bottom: var(--space); }
.font-set-roles { margin: 0.25rem 0 0 1.5rem; padding: 0; list-style: none; font-size: 0.9rem; }
.font-role { display: inline-block; min-width: 9rem; opacity: 0.7; }
.font-designer { opacity: 0.7; }
.asset-slot { margin-bottom: var(--space); }
.asset-preview img { max-width: 16rem; max-height: 8rem; display: block; margin-bottom: 0.5rem; background: var(--color-page, var(--color-paper)); }
.asset-empty { opacity: 0.6; }
.asset-status--error { color: var(--color-error); }
.fieldset { border: 0; padding: 0; margin: 0 0 var(--space); }
.fieldset legend { font-weight: bold; margin-bottom: 0.5rem; }

/* Slice 4 — clients & people, transcribed from the Figma 3.30 frames
   (7353:3426 list, 7108:18135 client, 7670:15492 person). STRUCTURE only:
   the brand blue tints and the GT Flexa display face are REFRESH-layer
   (Chris-selected tokens, not a session's call), so every tint below rides
   a token with a neutral fallback — Jessica/Chris swap the tokens, the
   anatomy holds. The ui-green/ui-red are Figma's own semantic UI colors,
   carried as defaults and flagged in the build log. */
:root {
    --color-rule: #9a9a9a;        /* Figma: brand @ 70% */
    --color-rule-soft: #d9d9d9;   /* Figma: brand @ 85–90% */
    --color-tint: #ececec;        /* Figma: brand @ 85% (table heads) */
    --color-faded: #9a9a9a;       /* Figma: brand @ 70% (archived rows) */
    --color-ui-green: #00ad43;
    --color-ui-red: #ff5320;
    --font-display: var(--font-ui);
}

.page-header { display: flex; align-items: flex-end; justify-content: space-between; gap: var(--space); border-bottom: 4px solid var(--color-rule); padding-bottom: 0.75rem; margin-bottom: 1.5rem; }
.page-header h1 { margin: 0; }
/* Every page title is Lorien 34/400 (the Wave 3 walk, Sep 2: the legacy pages' h1 rendered in the Circular stand-in at 700/30 — a stale rule). The masthead's 26px is its own scale, ruled later in this file; the size question is Chris's. */
body.studio h1 { font: 400 34px/1.1 var(--display); letter-spacing: 0; color: var(--ink); }
.page-actions { margin: 0; }
a.button { display: inline-block; background: var(--color-ui-green); color: #fff; border-radius: 3px; padding: 0.85rem 1rem; font-size: 1rem; line-height: 1.15; text-decoration: none; text-align: center; }

.clients .empty-state, .client .empty-state, .person .empty-state { font-family: var(--font-text); font-size: 1.1rem; }
.clients-table { border-collapse: collapse; width: 100%; }
.clients-table th, .clients-table td { border: 2px solid var(--color-rule); text-align: left; padding: 0.6rem 1.25rem; }
.clients-table th { background: var(--color-tint); font-size: 1rem; font-weight: 900; }
.clients-table td { background: #fff; font-size: 1.15rem; padding: 1rem 1.25rem; }
.clients-table td a { color: inherit; font-weight: 600; }

.client-details, .person-details { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.75rem 2rem; margin: 0 0 2rem; }
.client-details > div, .person-details > div { display: flex; gap: 0.5rem; }
.client-details dt, .person-details dt { font-size: 0.85rem; font-weight: 900; line-height: 1.6; white-space: nowrap; }
.client-details dt::after, .person-details dt::after { content: ":"; }
.client-details dd, .person-details dd { margin: 0; font-size: 0.95rem; line-height: 1.4; }

.client h2, .person h2 { font-weight: 700; font-size: 2rem; letter-spacing: -0.02em; line-height: 1; margin: 2.5rem 0 0.75rem; }
.client-people h2, .client-projects h2, .person-clients h2 { border-bottom: 4px solid var(--color-rule); padding-bottom: 0.75rem; }

.people-list, .projects-list, .person-clients-list { list-style: none; margin: 0; padding: 0; }
.people-list li, .person-clients-list li { display: flex; align-items: baseline; gap: 1.5rem; padding: 1.25rem 0; border-bottom: 1px solid var(--color-rule-soft); }
.people-list li > a:first-child, .person-clients-list li > a:first-child { font-size: 1.35rem; font-weight: 900; letter-spacing: -0.02em; color: inherit; }
.person-role, .relationship-role { font-size: 1.15rem; }
.person--archived, .relationship--archived { color: var(--color-faded); }
.person--archived a, .relationship--archived a { color: var(--color-faded); }
.person-status, .relationship-status { font-size: 0.8rem; font-weight: 900; letter-spacing: 0.1em; text-transform: uppercase; }
.person-edit, .relationship-edit { margin-left: auto; font-size: 0.85rem; }

.projects-list li { padding: 0.5rem 0; border-bottom: 1px solid var(--color-rule-soft); }
.projects-list .form, .client-projects > .form { display: flex; align-items: flex-end; gap: 0.75rem; }
.projects-list .form .field, .client-projects > .form .field { margin-bottom: 0; flex: 1; }

.client-danger, .person-danger { border-top: 1px solid var(--color-rule-soft); margin-top: 2.5rem; padding-top: 0.5rem; text-align: right; }
.client-danger h2, .person-danger h2 { display: none; }
.client-danger p, .person-danger p { font-size: 0.85rem; text-align: left; }
.client-danger button, .person-danger button { background: none; border: 0; padding: 0; color: var(--color-ui-red); font-size: 0.85rem; font-weight: 900; cursor: pointer; }

.partial-date-inputs { display: flex; gap: 0.5rem; }
.partial-date-inputs input { width: 5rem; }

/* Slice 5 — invoices core. The list and the client list's money columns ride
   slice 4's ruled-table anatomy (the hub frames share it). NOT transcribed —
   shipped plain and FLAGGED in the build log: the invoice list frame proper
   (figma 6767-66709), the edit frame (6767-71744), the status badge, the
   filter row, the document detail, the edit form's row tables. */
.invoices-table { border-collapse: collapse; width: 100%; }
.invoices-table th, .invoices-table td { border: 2px solid var(--color-rule); text-align: left; padding: 0.6rem 1.25rem; }
.invoices-table th { background: var(--color-tint); font-size: 1rem; font-weight: 900; }
.invoices-table td { background: #fff; font-size: 1.15rem; padding: 1rem 1.25rem; }
.invoices-table td a { color: inherit; font-weight: 600; }
.invoices-table th.numeric, .invoices-table td.numeric,
.clients-table th.numeric, .clients-table td.numeric { text-align: right; }
.client-billed { display: block; white-space: nowrap; }
.list-filter { margin-bottom: var(--space); }
.list-filter a { margin-right: var(--space); }
.list-filter a[aria-current="page"] { font-weight: 900; text-decoration: none; }
.invoice-meta { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.75rem 2rem; margin: 0 0 2rem; }
.invoice-meta dt { font-size: 0.85rem; font-weight: 900; }
.invoice-meta dd { margin: 0 0 0.5rem; }
.invoice-lines { border-collapse: collapse; width: 100%; margin-bottom: 2rem; }
.invoice-lines th, .invoice-lines td { text-align: left; padding: 0.5rem 0.75rem; border-bottom: 1px solid var(--color-rule-soft); }
.invoice-lines .numeric { text-align: right; }
.invoice-lines td small { display: block; opacity: 0.7; }
.invoice-total th, .invoice-total td { font-weight: 900; border-bottom: 0; border-top: 2px solid var(--color-rule); }
.invoice-edit-lines, .invoice-edit-adjustments { width: 100%; }
.invoice-edit-lines th, .invoice-edit-adjustments th { text-align: left; font-size: 0.85rem; }
.invoice-edit-lines input, .invoice-edit-adjustments input { width: 100%; box-sizing: border-box; }
.invoice-activity ul { list-style: none; margin: 0; padding: 0; }
.invoice-activity li { display: flex; gap: 1rem; padding: 0.4rem 0; border-bottom: 1px solid var(--color-rule-soft); }
.activity-when { font-size: 0.85rem; opacity: 0.7; white-space: nowrap; }

/* ═══════════════════════════════════════════════════════════════════════════
   THE FOUNDATION — Aug 27–29 design sitting, transcribed slice 6c.
   design/invoice-edit.html WAS the spec (deleted Aug 31 — the built page is the spec now; git has the prototype); its CSS and markup are the design
   (its <script> was demo harness — none of it ported). Adaptations here are
   mechanical scoping only, each noted at its rule:
     · the prototype's body/html frame rules  → .frame (the shell adopts it
       when slice 7 restyles the studio surface)
     · bare label/input rules                 → .f, the labeled-field class
     · .sec:first-child masthead placement    → .sec--mast, an explicit class
     · the ··· menu toggle                    → <details class="more"> — the
       platform's own disclosure (no JS for what the platform does, Aug 29)
   Tokens live in tokens.css. Where the prototype is silent we ship plain and
   FLAG in the build log — never invent.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── the frame: a column — the MASTHEAD, then the BODY (rail beside content),
   then the footer (the chrome pass, Sep 3) — one bordered box centred on the
   deeper tint. In the shell this is body (html gets --outside); as a
   component it is .frame inside the styleguide. The body is a grid; the
   frame is a flex column so the footer is a sibling of the grid, not a cell
   of it (Chrome bounds a sticky element by the grid CONTAINER, not its area
   — a footer inside the grid gets overlapped by the sticky rail). ── */
.frame, .frame *, .paper, .paper * { box-sizing: border-box; }
.frame{font:15px/1.5 var(--ui);color:var(--ink);background:var(--panel);display:flex;flex-direction:column;min-height:100vh;
  max-width:calc(var(--rail-w) + var(--content) + 2*var(--cardpad) + 2*var(--gx) + 6px);margin:0 auto;border-left:var(--line);border-right:var(--line)}   /* 6px: the frame's two edges and the content column's left (THE BORDER RULE, below) */
/* THE BORDER RULE (ruled Sep 2, evening, both axes): a rule belongs to the thing AFTER it — a cell draws its TOP, a section its top, a panel its top, the footer its top, a column its LEFT; a table's outer box draws the outside. Nothing is drawn twice, so nothing doubles or misaligns. Every cell below follows it: the rail's items draw their top, the content column its left, a tab its left, an action its left, a line item its top. */
.frame>.body{flex:1;display:grid;grid-template-columns:var(--rail-w) 1fr}
.frame>.body>.main{border-left:var(--line);min-width:0}   /* the content column draws its left — the rail draws nothing on its right */
.frame a{color:inherit;text-decoration:none}

/* ── THE MASTHEAD (ruled Sep 3): the lockup and the bar are ONE sticky row
   across the frame — 9u plus its line — so the rule under the lockup and the
   rule under the bar are the same border of the same element, aligned by
   construction. It is the one sticky exception to the border rule (its line
   must travel with it), so it is sized as its cell PLUS its line (--mast).
   This retires the intersection bug: the bar was 48 border-box with its line
   inside (46–48) against the rail's first line (48–50); now there is one
   line, the masthead's. Named for the view transition so it stays ABOVE the
   rows in the transition layer (unnamed, rows surfaced over the bar — Aug 31). ── */
.frame>.mast{position:sticky;top:0;z-index:5;display:grid;grid-template-columns:var(--rail-w) 1fr;height:var(--mast);border-bottom:var(--line);background:var(--tint);view-transition-name:mast}
.mast .brand{height:var(--bar);display:flex;align-items:center;padding:0 16px;color:var(--ink)}   /* 16 not 24: the lockup's artwork wants the width — at 16 it lands at the legacy's own scale (~21px of art), the one cell that bleeds past the text column */
.mast .brand .swmark{width:100%;height:auto;display:block}   /* height from the cropped ratio (294:40) — never set; the chevron is var(--acting) inside the SVG */

/* ── rail: a column of cells — the nav items only, since the mark moved up
   into the masthead (Sep 3). Cells run edge to edge — their lines meet the
   rail's border, the canvas's edge. The first item draws no top: the
   masthead already drew that line. ── */
.rail{background:var(--tint);display:flex;flex-direction:column;position:sticky;top:var(--mast);height:calc(100vh - var(--mast) - var(--foot))}   /* the frame is the light L (rail + masthead on --tint); the content panel behind is --panel (Aug 31). Sticky under the masthead, its height leaves room for the FOOTER — 100vh − masthead − footer — so at the bottom of the scroll its bottom meets the footer's top with nothing to push it up (measured Sep 3: rail 74–1217, HOME 74–122 unmoved, footer 1217.8 — nothing slides) */
.rail::after{content:"";flex:1;border-top:var(--line)}   /* the rail's rule under its last item: the empty rest of the rail is "the thing after it" and draws its top */
.frame>.body{background:linear-gradient(to right,var(--tint) 0 var(--rail-w),transparent var(--rail-w))}   /* mid-scroll the rail element stops --foot short of the body's bottom; the body paints the rail's tint into its first --rail-w so the column below it is still the rail's ground, derived from the same token */
.rail a.item{height:var(--fh);display:flex;align-items:center;padding:0 24px;border-top:var(--line);font:500 12px/1.3 var(--ui);letter-spacing:.08em;text-transform:uppercase;color:var(--ink2);text-decoration:none;overflow-wrap:anywhere}   /* nothing crosses the rail's border: a word that can't fit wraps at the edge. (The studio's NAME no longer lives here — F34 revised Sep 1, the first item is "Home" — so no cell ever needs to grow; the corpus's long names are the list pages' concern.) */
.rail a.item:first-child{border-top:0}   /* the masthead already drew this line */
.rail a.item.on{color:var(--ink);background:var(--highlight)}   /* the studio's highlight */
/* ── chrome hover (Aug 31, late): a cell takes the PANEL — the content's own ground — and ink, saying "this is about to be the page"; the active cell keeps its highlight. One ease for all chrome; CSS transitions are the platform's.
   THE OTHER GROUND (ruled Sep 3): where a chrome cell sits ON --panel — the content's ground — its hover goes LIGHTER, to --tint; same rule, the other ground (the Home clock is the first case; `.card .go.quiet` already does it). Every hover-to-panel below sits on --tint: the rail, the tabs, the ··· menu, the list's rows, the footer. ── */
.rail a.item,.bar .tabs a,.bar .btn,.menu a,.menu button{transition:background-color .15s ease,color .15s ease}
.rail a.item:hover,.bar .tabs a:hover{background:var(--panel);color:var(--ink)}
.rail a.item.on:hover,.bar .tabs a.on:hover{background:var(--highlight)}

/* ── the bar: a CELL of the masthead (Sep 3) — static, no bottom border (the
   masthead draws it), drawing its LEFT: the content column's line. Inside
   the 72 bar everything is a 48 cell with 12 of air above and below, never
   full-height (RULED Sep 3 afternoon, tried live against full-height tabs).
   Tabs on the left as ONE ENCLOSED BOX on the content edge — each tab
   bordered like a clock cell, the first drawing its left; the on-tab in the
   highlight (a place). The ··· and the actions on the right take the same
   48-with-air, the filled primary included, the last closing the strip on
   the content's right edge. ── */
.bar{display:flex;align-items:center;height:var(--bar);background:var(--tint);border-left:var(--line)}
.bar>*{display:flex;align-items:center;height:var(--fh)}
.bar .tabs{margin-left:var(--content-edge);margin-right:auto}   /* border-box: outer edges meet the fields' outer edges, no arithmetic */
.bar .tabs:empty{display:none}   /* a page with no tabs draws no stray box at the content edge */
.bar .tabs a{height:100%;display:flex;align-items:center;padding:0 16px;font:500 11px/1 var(--ui);letter-spacing:.08em;text-transform:uppercase;color:var(--ink2);border:var(--line);border-left:0;text-decoration:none}   /* the clock strip's grammar one size up: 11px caps, each cell drawing its top, right and bottom; the strip's first draws the left */
.bar .tabs a:first-child{border-left:var(--line)}
.bar .tabs a.on{background:var(--highlight);color:var(--ink)}   /* WHERE YOU ARE = the studio's highlight, like the active nav cell (ruled Aug 31, Chris — settles the Aug 28 open question). What you CHOSE (Fixed|Per unit) stays white: a chosen value is a field. What the product DOES is --acting. */

/* ── the ··· menu: a <details> disclosure (adaptation: the prototype toggled
   a class from script; the platform already does this). A column of --fh
   cells hanging off the ··· cell, made of the line, its top border
   overlapping the masthead's so there is one line. Record actions first;
   destructive ones last, quieter. Template CHOICE is not here (it belongs
   to creation); Change template… is. ── */
details.more{position:relative}
.bar>.more,.bar>.acts:not(:empty){border-top:var(--line);border-bottom:var(--line)}   /* the right-hand box: the ··· and the actions share one enclosure of the line; each cell draws its left, the last its right */
.bar>.more:has(+.acts:empty) summary{border-right:var(--line)}   /* a record with only the ··· (voided): the cell closes itself */
.more summary{list-style:none;height:100%;display:flex;align-items:center;font-size:18px;color:var(--ink2);padding:0 20px;letter-spacing:.1em;border-left:var(--line);cursor:pointer}
.more summary::-webkit-details-marker{display:none}
.more[open] summary{background:#fff}   /* an open menu's cell is "selected": white, like a tab */
.menu{position:absolute;top:100%;right:-2px;min-width:calc(28*var(--u));background:var(--tint);border:var(--line);z-index:6}
.bar .menu{top:calc(var(--fh) - 2px + (var(--bar) - var(--fh)) / 2)}   /* drops from the masthead's LINE, not the cell's: from the cell's padding box (2 inside its own top line) down the cell's 48 and the 12 of air — so the menu's top border lies exactly ON the masthead's line and its first row starts under it. (Before Sep 8 it was `100% + air`, and 100% of a border-box cell is 44, not 48: the menu landed 4 too high, its first row's top clipped under the bar's line — Chris saw it.) */
.bar>.more:has(+.acts:empty) .menu{right:0}   /* when the ··· closes itself, the menu's right edge is its own */
.menu a{display:flex;align-items:center;height:var(--fh);padding:0 24px;font:500 12px/1 var(--ui);letter-spacing:.08em;text-transform:uppercase;color:var(--ink);border-top:var(--line);text-decoration:none}
.menu a:first-child{border-top:0}
.menu a:hover{background:var(--panel);color:var(--ink)}
.menu a.danger{color:var(--ink2)}
.bar .acts{margin-right:var(--content-edge)}
.bar .btn{height:100%;border:0;border-left:var(--line);border-radius:0;padding:0 24px;font:500 12px/1 var(--ui);letter-spacing:.08em;text-transform:uppercase;background:transparent;color:var(--ink);cursor:pointer}
.bar .btn.primary{background:var(--acting);color:#fff}   /* the product acts in the brand hue — the ACTING brand, lightness-capped (tokens) */

/* ── THE FOOTER IS THE SESSION (ruled Sep 6; the chrome pass of Sep 3 gave it its shape): the frame's last row, a sibling
   of the body so the sticky rail stops where it begins. A grid on the line, left to right: the STUDIO in the rail-width
   cell — short, matching the lockup column, its rule one line with the content column's left — then equal centred cells,
   each drawing its LEFT: the signed-in PERSON's email (→ Settings ▸ Account: "who am I logged in as"), support, LOG OUT
   as a POST cell (the Keep pattern: the form is display:contents, the button the cell), and PAY CREATIVES BETTER™
   rightmost (the mark must appear in the product or the trademark lapses). The social icons retired to the marketing
   site and the hub. Caps voice; hover = panel + ink, the chrome's ease. --foot is its height plus its line. ── */
.foot{display:grid;grid-template-columns:var(--rail-w) minmax(0,1fr);min-height:var(--bar);border-top:var(--line);background:var(--tint);font:500 12px/1 var(--ui);letter-spacing:.08em;text-transform:uppercase;color:var(--ink2)}
.foot .cells{display:grid;grid-auto-flow:column;grid-auto-columns:minmax(0,1fr)}
.foot .cells form{display:contents}
.foot .studio,.foot .cells a,.foot .cells button{display:flex;align-items:center;justify-content:center;gap:0 .5ch;padding:0 16px;min-height:var(--bar);border-left:var(--line);text-align:center;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font:inherit;letter-spacing:inherit;text-transform:inherit;color:inherit;background:none;border-top:0;border-right:0;border-bottom:0;border-radius:0;cursor:pointer;transition:background-color .15s ease,color .15s ease}
.foot .studio{border-left:0;color:var(--ink);display:block;line-height:var(--bar)}   /* the rail's column: the studio's name, short — an ellipsis rather than a wrap */
.foot .who{text-transform:none;letter-spacing:0}   /* an address is a code */
.foot .us{color:var(--ink)}
.foot .studio:hover,.foot .cells a:hover,.foot .cells button:hover{background:var(--panel);color:var(--ink)}
@media (max-width:855px){.foot{grid-template-columns:1fr}.foot .cells{grid-auto-flow:row;grid-auto-columns:auto}.foot .studio,.foot .cells a,.foot .cells button{border-left:0;border-top:var(--line);white-space:normal}.foot .studio{border-top:0}}

/* ── the form is rows of the page; sections are edge-to-edge cells; THE grid
   lives inside each row (adaptation: the prototype's #form is .page) ── */
.page{padding:0 var(--gx)}
.card{padding:0 var(--cardpad);position:relative;container-type:inline-size;container-name:card}
.card h2{font:500 11px/1 var(--ui);letter-spacing:.08em;text-transform:uppercase;color:var(--ink3);margin:0 0 calc(3*var(--u))}   /* a heading is a row; rows are 3u apart */
.sec{margin:0 calc(-1*var(--gx) - var(--cardpad));padding:calc(4*var(--u)) calc(var(--gx) + var(--cardpad));border-top:var(--line)}   /* 4u above and below, every section; rows 3u apart; cells 6u — one lattice */
.sec:first-child{border-top:0}
.g{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:var(--rowgap) var(--gutter);align-items:start}   /* ERRORS NEVER MOVE THE ROW (ruled Sep 5): the row aligns to the TOP of its cells, so a message under one field (part of the field's own cell) never lifts its neighbours — by construction, once, for every row; the prototype's align-items:end was the lift */
.g>:where(:not(.f):has(>.mode)){align-self:end}   /* the one label-less cell in a labelled row — the line's Fixed · Per unit toggle — sits on the fields' baseline; :where keeps it below any cell's own align-self */
.c12{grid-column:span 12}.c11{grid-column:span 11}.c10{grid-column:span 10}.c9{grid-column:span 9}.c8{grid-column:span 8}.c7{grid-column:span 7}
.c6{grid-column:span 6}.c5{grid-column:span 5}.c4{grid-column:span 4}.c3{grid-column:span 3}.c2{grid-column:span 2}.c1{grid-column:span 1}
.g.pair{align-items:start}   /* a row of a field beside a control group aligns to the top, so their labels and their controls are level */

/* ── the labeled field (adaptation: the prototype's bare label/input rules,
   scoped to .f — the labeled-field component's class). Three states: on;
   off = the same line, the ground showing through (Aug 31: the fill carries
   the state; the faded line was retired), text at caption grey; computed = no box,
   right-aligned text. ── */
.f{display:block;min-width:0}
.f>span,.lbl{display:block;font:500 13px/1 var(--ui);color:var(--ink);margin-bottom:6px}   /* .lbl: the same label on things that aren't <label>s */
.f>span em{font-style:normal;font-weight:400;color:var(--ink3);margin-left:4px}   /* "optional" — in the label, quieter, never a placeholder */
.f input,.f select,.f textarea{width:100%;min-width:0;font:15px/1.3 var(--ui);color:var(--ink);background:#fff;border:2px solid var(--field);border-radius:0;padding:0 12px;height:var(--fh)}
.f textarea{height:auto;min-height:80px;resize:vertical;padding:12px}
/* alternative "A" for the palette sitting — hairline on white paper:
   .card{background:var(--paper);border:1px solid var(--rule);border-radius:4px}
   .f input{border:1px solid var(--rule2);border-radius:4px}  with --bg:#f3f1ec --rail:#ebe8e1 --rule:#e4e1da */
.f input.mono{font-family:var(--mono);font-size:14px}
.f input.n{text-align:right}
.f input:focus,.f select:focus,.f textarea:focus{outline:0;border-color:var(--ink);background:var(--highlight)}
.f input::placeholder,.f textarea::placeholder{color:var(--ink3)}
.f .ro{height:var(--fh);display:flex;align-items:center;font-family:var(--mono);font-size:14px;color:var(--ink2);justify-content:flex-end}
.f:has(> .ro)>span{text-align:right}   /* a label aligns with what it labels: inputs are left-aligned boxes, computed values are right-aligned text */
.f.off>span{color:var(--ink3)}
.f.off input{border:var(--line);background:transparent;color:var(--ink3)}   /* off = THE line, unfaded; the fill says it (on = white window, off = the ground showing through). The faded 20% line (Aug 30) was a second signal for the same state and vanished on the deeper panel — retired Aug 31. */

/* ── the masthead: the paper's own header — a row of its own: h1, status as
   a quiet line. The business box sits beside the two fixed field rows and
   STRETCHES to them — a FIELD whose editor lives in Settings: the line,
   yellow on hover, a pencil. Custom fields drop to a third row.
   (Adaptation: .sec--mast, an explicit class for the prototype's
   .sec:first-child placement rules.) ── */
/* The field pairs alternate 7–9 / 10–12 by CHILD position (slice 11: the Send
   dial is a <div class="f">, not a <label>, so nth-of-type would break the
   alternation): children are .mast, .c6, .bizcell, then the fields. */
.sec--mast .g>.f:nth-child(even){grid-column:7 / span 3}
.sec--mast .g>.f:nth-child(odd){grid-column:10 / span 3}
.mast{grid-column:1 / span 6}
.mast h1{font:400 26px/1.1 var(--display);margin:0 0 6px;color:var(--ink)}   /* with 4u section padding its centre lands ~on the rail's first line — a happy consequence, not the rule */
.mast .st{font:500 11px/1 var(--ui);letter-spacing:.08em;text-transform:uppercase;color:var(--ink2);margin:0}
.mast .tpl a:hover{color:var(--ink);text-decoration:underline}   /* the template the invoice came from — the one place templates are advertised */
.bizcell{grid-column:1 / span 6;grid-row:2 / span 2;align-self:stretch;display:flex;flex-direction:column}   /* a proper half: shares the h1's right edge */
.biz{flex:1;display:block;border:var(--line);padding:12px 16px;position:relative;color:var(--ink2);font-size:13px;line-height:1.5;text-decoration:none}   /* the paper's own voice (13/1.5): six lines = 117 inside 12px paddings fit the two field rows (145) — the block is BOUNDED by construction (InvoiceController::businessBlock caps it), never measured (ruled Sep 2) */
.biz b{color:var(--ink);font-weight:500}
.biz:hover{background:var(--highlight);color:var(--ink)}
.biz::after{content:'';position:absolute;top:10px;right:10px;width:14px;height:14px;opacity:0;background:no-repeat center/contain url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M11.5 1.5l3 3L5 14H2v-3z' fill='none' stroke='%2317171a' stroke-width='1.5' stroke-linejoin='round'/%3E%3C/svg%3E")}
.biz:hover::after{opacity:1}
/* ADDS ARE ACTIONS, NOT LINKS (ruled Sep 4, the editor sitting — lands here ONCE, the rule for every editor): the bar's
   box construction at 32 — a `+` cell and the word, divided by the line, both on the ground; the whole button lifts to
   the TINT on hover (the adds sit on the panel; hover is always the OTHER ground). Ink +, 11 caps. Tried and rejected: the
   + cell on acting green (competes with PUBLISH — seven of them on the invoice editor), on --field, on --rule (four points
   from the panel, invisible), a two-tone hover. The OFF state of a presence-as-data add is the same button with a −
   (− REMOVE ITEM DATES): one button in two states. <a class="add"> and <button class="add"> are the same thing. */
.add,button.add{display:inline-flex;align-items:center;height:calc(4*var(--u));padding:0 12px 0 0;margin:0;border:var(--line);border-radius:0;background:transparent;font:500 11px/1 var(--ui);letter-spacing:.08em;text-transform:uppercase;color:var(--ink2);white-space:nowrap;cursor:pointer;text-decoration:none;transition:background-color .15s ease,color .15s ease}
.add:before{content:"+";display:flex;align-items:center;justify-content:center;width:calc(4*var(--u) - 2px);height:100%;margin-right:12px;border-right:var(--line);font-size:14px;font-weight:400;color:var(--ink)}
.add.off:before{content:"\2212"}   /* the minus sign, not a hyphen */
.add:hover,button.add:hover{background:var(--tint);color:var(--ink)}
.adds{display:flex;gap:8px;flex-wrap:wrap;margin-top:calc(3*var(--u))}
.adds .grp{display:flex;gap:8px;flex-wrap:wrap}
.adds .grp.end{margin-left:auto}   /* right-aligned in the row; when the row wraps, still right-aligned on its own line — by construction */

/* ── line items: fixed three-row shape under a header row (number ·
   move up/down · delete) that replaces the extra air between items;
   connectives are LABELS (× Rate, per); the row ends in its Amount; dim not
   vanish ── */
.line{padding:calc(3*var(--u)) 0}
.line+.line,.line+.adj,.adj+.adj{border-top:1px solid var(--rule)}   /* the soft 1px rule — the one deliberately soft stroke on the page; the row after draws it (the border rule) */
h2+.line{padding-top:0}   /* the first item's air is the heading's own */
.itemrow{display:flex;align-items:center;gap:16px;height:calc(3*var(--u));margin-bottom:calc(2*var(--u));font:500 12px/1 var(--ui);color:var(--ink3)}
.itemrow .n{font-family:var(--mono);color:var(--ink2)}
.itemrow a{color:var(--ink3);text-decoration:none}
.itemrow a:hover{color:var(--ink)}
.itemrow .del{margin-left:auto}
.line .g{row-gap:calc(2*var(--u))}
.mode{display:flex;border:2px solid var(--field);border-radius:0;overflow:hidden;width:100%;height:var(--fh);align-items:stretch}
.mode a{flex:1;display:flex;align-items:center;justify-content:center;font:500 12px/1 var(--ui);white-space:nowrap;color:var(--ink3);text-decoration:none}
.mode a.on{background:#fff;color:var(--ink)}   /* a chosen segment is white, like a selected tab; the brand hue belongs to the primary action alone */
.mode a+a{border-left:var(--line)}   /* the divider: the toggle IS the tab component at field size */
/* TOGGLES (ruled Sep 4, lands here once): the chosen segment stays white; an unselected segment lifts to the tint on
   hover — the same family as the adds: cells on the line, hover lifts the cell to the other ground. */
.mode a,.mode button{transition:background-color .15s ease,color .15s ease}
.mode a:hover,.mode button:hover{background:var(--tint);color:var(--ink)}
.mode a.on:hover,.mode button.on:hover{background:#fff}
.totals{display:grid;grid-template-columns:1fr 1fr;gap:var(--u) 0;margin:calc(3*var(--u)) 0 0 auto;font-size:14px;
  width:calc((100% - 11*var(--gutter))/12*4 + 3*var(--gutter))}   /* cols 9–12 by construction; labels left on col 9, values right on col 12; no column gap so the rule is one line */
.totals .k{color:var(--ink2)}.totals .v{text-align:right;font-family:var(--mono)}
.totals .big{font:400 18px/1 var(--display);padding-top:calc(1.5*var(--u));border-top:1px solid var(--ink)}
.totals .big.v{font-family:var(--mono);font-weight:500;font-size:18px}

/* ── pay by (SILENT in the spec beyond this: checkbox styling should become
   the line — FLAGGED, shipped plain as the prototype had it; the pay-by
   block itself is parked, Aug 28, and is NOT on the paper) ── */
.chk{display:flex;align-items:center;gap:10px;font-size:14px;height:32px;color:var(--ink2)}
.chk i{width:15px;height:15px;border:1px solid var(--rule2);border-radius:3px;display:inline-block}
.chk.on{color:var(--ink)}.chk.on i{background:var(--ink);border-color:var(--ink)}

/* ── the paper lives in paper.css (slice 9): ONE stylesheet for the one
   document, linked by the studio shell AND the client shell — the pay page
   renders the same partial with the same CSS, never a copy. ── */

/* ── reorder animation: VIEW TRANSITIONS, same-document only. Each item
   carries a stable view-transition-name (its id, never its position); this
   one rule animates tiles from where they were to where they are when
   live.js swaps the page in. NOT cross-document (Aug 31): the platform can't
   hold scroll across two documents, so a cross-document transition animated
   the scroll reset — with JS off the ops simply navigate (PRG, instant, top
   of page), which is the honest fallback. Movement only: the old/new
   snapshot cross-fade is off and the root never animates. ── */
::view-transition-group(*){animation-duration:.4s;animation-timing-function:cubic-bezier(.2,.7,.2,1)}
::view-transition-group(root){animation:none}
::view-transition-old(*),::view-transition-new(*){animation-duration:.15s}   /* the browser's own cross-fade, short: a row that changes in place (the toggle, the format) eases instead of cutting; a row that moves fades as it slides. display:none on the old snapshot was the fix for two OPAQUE images ghosting — with the fade back, the blend is correct (Aug 31, late) */

/* ── the one viewport breakpoint: rail beside content, or rail as a top bar
   (856 = rail + 2×gutter + a 640 form container). Finer stacked-nav styling
   under 856 is on the silent list — FLAGGED, shipped as the prototype had
   it. ── */
@media (max-width:855px){
  .frame>.mast{grid-template-columns:auto 1fr}   /* the lockup's cell is as wide as the mark */
  .mast .brand .swmark{width:auto;height:calc(3*var(--u))}   /* in the top bar the cell is as wide as the mark: height leads */
  .frame>.body{grid-template-columns:1fr}
  .rail{position:static;height:auto;flex-direction:row;align-items:stretch;gap:0;padding:0;overflow-x:auto;border-bottom:var(--line)}   /* the rail as a row under the masthead draws its bottom — the content below it is "the thing after" (as the prototype had it; the stacked nav's finer styling is on the silent list, FLAGGED) */
  .frame>.body>.main{border-left:0}
  .rail a.item{padding:0 14px;display:flex;align-items:center;white-space:nowrap;border-top:0;border-left:var(--line)}
  .rail a.item:first-child{border-left:0}   /* the frame's edge is its left */
  .rail::after{border-top:0;border-left:var(--line)}   /* in a row the rest of the rail draws its LEFT, closing the last item */
  .frame>.body{background:none}
}
/* ── everything inside responds to its container, not the viewport ── */
@container card (max-width:640px){
  .c1,.c2,.c3,.c4,.c5,.c6,.c7,.c8,.c9,.c10,.c11{grid-column:span 12}
  .currency,.fmt,.notecell{grid-column:span 12}
  .fmt,.notecell{grid-row:auto}   /* the money cluster stacks like everything else under 640 */
  .deposit .dial{grid-column:span 12;margin-top:0}
}

/* ── designer's grid overlay, derived from --gutter. Inset matches each
   host's real padding. The prototype's `g` keypress was demo harness; no
   production toggle ships — add body.grid from devtools. ── */
body.grid .page .card::before{inset:0 var(--cardpad)}
body.grid .paper::before{inset:0 var(--content-edge)}
body.grid .page .card::before,
body.grid .paper::before{content:'';position:absolute;
  --ov:color-mix(in oklab, var(--brand) 10%, transparent);
  background:repeating-linear-gradient(to right,
    var(--ov) 0,
    var(--ov) calc((100% - 11*var(--gutter))/12),
    transparent calc((100% - 11*var(--gutter))/12),
    transparent calc((100% - 11*var(--gutter))/12 + var(--gutter)));
  pointer-events:none;z-index:9}

/* ── styleguide accommodation: foundation samples are wider than the neutral
   48rem column ── */
.styleguide-sample{overflow-x:auto}

/* ═══════════════════════════════════════════════════════════════════════════
   SLICE 7 — the lifecycle wired onto the foundation. Everything here is
   either (a) the platform's own controls wearing the prototype's rules —
   buttons where the prototype drew links, because state changes are POSTs
   and ops are submits — or (b) a state the spec is SILENT on, shipped plain
   and FLAGGED in the build log. Nothing invented past that.
   ═══════════════════════════════════════════════════════════════════════ */

/* (a) buttons that ARE the prototype's links: same rules, no button chrome */
.itemrow button,.mode button,.menu button{font:inherit;background:none;border:0;padding:0;margin:0;color:inherit;cursor:pointer;text-align:inherit}
.itemrow button{color:var(--ink3)}
.itemrow button:hover{color:var(--ink)}
.itemrow button.del{margin-left:auto}
.mode button{flex:1;display:flex;align-items:center;justify-content:center;font:500 12px/1 var(--ui);white-space:nowrap;color:var(--ink3)}
.mode button.on{background:#fff;color:var(--ink)}
.mode button+button{border-left:var(--line)}
.mode button:disabled{color:var(--ink3);cursor:default;opacity:.55}   /* a segment that is present, not pressable (Kickoff 8: the Auto dial's Charge without a card on file) — plainly disabled, no explanatory text (Rulings II). FLAGGED: undesigned */
.mode button:disabled:hover{background:transparent;color:var(--ink3)}
.menu form{display:block}
.menu button{display:flex;align-items:center;width:100%;height:var(--fh);padding:0 24px;font:500 12px/1 var(--ui);letter-spacing:.08em;text-transform:uppercase;color:var(--ink)}
.menu>*+*{border-top:var(--line)}
.menu a{border-top:0}
.menu button:hover{background:var(--panel);color:var(--ink)}
.menu button.danger{color:var(--ink2)}
.bar .acts form{display:contents}
.bar .acts a.btn{display:flex;align-items:center;text-decoration:none}
.bar .acts>:last-child .btn,.bar .acts>.btn:last-child{border-right:var(--line)}   /* the last action closes the strip; every action draws its left */
.bar .acts .btn.primary:hover{filter:brightness(1.1)}
.bar .btn:hover{background:var(--panel);color:var(--ink)}
.bar .btn.primary:hover{background:var(--acting);color:#fff}   /* the FILLED button never takes ink on hover (ruled Sep 6) — it lifts its fill only (the brightness above), text unchanged; "panel + ink on hover" is for chrome CELLS on the panel ground */
.f input[type=date]{font-family:var(--mono);font-size:14px}
.mast-add{grid-column:7 / span 6}
.sec--mast .g .mast-add{align-self:end;margin-top:0}   /* slice 11: an .adds row (Add a field · Make recurring) — the grid's row gap is its spacing */
/* Slice 11 — an action with a menu (the Invoices page's New): the ··· disclosure's construction, the button as its summary. */
.bar .acts details.act{position:relative;height:100%}
.bar .acts details.act summary{list-style:none;cursor:pointer;height:100%;display:flex;align-items:center}
.bar .acts details.act summary::-webkit-details-marker{display:none}
.bar .acts details.act .menu{right:0}
/* The default badge (F46: the FK carries the specialness; the list needs the badge — that's the whole price). Plain, FLAGGED. */
.badge{display:inline-block;margin-left:8px;padding:2px 6px;font:500 10px/1.4 var(--ui);letter-spacing:.08em;text-transform:uppercase;color:var(--ink2);border:var(--line)}
.nag.offer form{display:inline}
.nag.offer button{font:inherit;background:none;border:0;padding:0;margin-left:8px;color:var(--acting);cursor:pointer;text-decoration:underline}

/* (b) SILENT in the spec — plain, flagged. THE error rule (Aug 31): the
   field carries label, border, and message; no top-of-form list. */
.f.err>span{color:var(--color-error)}
.f.err input,.f.err textarea{border-color:var(--color-error)}
.f .msg{display:block;margin-top:6px;font:400 12px/1.3 var(--ui);color:var(--color-error)}
.nag{margin:calc(3*var(--u)) var(--content-edge) 0;padding:12px 16px;border:2px solid var(--highlight);background:var(--highlight);font-size:14px;color:var(--ink)}
.page .nag{margin-left:0;margin-right:0}
.linkline{margin:calc(2*var(--u)) var(--content-edge) 0;font-size:13px;color:var(--ink2)}
.page .linkline{margin-left:0;margin-right:0}
.linkline a{font-family:var(--mono);color:var(--acting);text-decoration:underline}
.adj{padding:calc(3*var(--u)) 0}
.adj .itemrow .n{font-family:var(--ui);letter-spacing:.08em;text-transform:uppercase;font-size:11px}
/* ── the foot's money cluster (Aug 31): Currency over Format at cols 9–12 —
   the totals' own columns, the page's money edge — and Note spanning both
   rows, its height DERIVED from the right stack (the bizcell construction:
   span + stretch + flex, textarea flex-basis 0 so its rows attribute never
   votes on track height). resize is off because the height is derived. ── */
.currency{grid-column:9 / span 4}
.fmt{grid-column:9 / span 4;grid-row:2}
.fmt .mode{font-family:var(--mono);font-size:14px}   /* the options ARE renderings — the paper's voice, not button chrome */
.notecell{grid-column:1 / span 6;grid-row:1 / span 2;align-self:stretch;display:flex;flex-direction:column}
.notecell .f{flex:1;display:flex;flex-direction:column}
.notecell textarea{flex:1 1 0;min-height:0;resize:none}
.quiet{color:var(--ink3);font-size:13px;margin:0}
.links .mono{font-family:var(--mono);font-size:12px}
.links form{margin-left:auto}
.links button.del{font:inherit;background:none;border:0;padding:0;color:var(--ink3);cursor:pointer;font-size:12px}
.links button.del:hover{color:var(--ink)}
body.studio .flash{margin:calc(2*var(--u)) var(--content-edge) 0}   /* on the content's own edges, like .nag (Chris, Sep 5): the flash was inset only --gx, the frame's outer padding, and stood proud of the grid */

/* ── THE LIST (the Wave 3 walk, Sep 2 — from prototypes/hub.html's tables; the
   list component): a box of the line; the head row on --panel in the caps
   voice; 48px rows on the light ground (--tint), the row a link, hover the
   panel (two tints, never a third); columns on minmax(0, Nfr) with a 32
   gap; numbers in IO right-aligned; ONE action at the right in --acting;
   the "now" states as a mark in the highlight under the words only. THE
   BORDER RULE: the box draws the outside, each row its top. ── */
.list{border:var(--line);background:var(--tint);--cols:1fr;display:grid;grid-template-columns:var(--cols);column-gap:calc(4*var(--u))}   /* ONE grid for the whole list: every row is a subgrid of it, so an auto track (↑↓, the action) resolves once, over every row — never per row */
.list .head,.list .row,.list .empty{grid-column:1 / -1}
.list .head,.list .row{display:grid;grid-template-columns:subgrid;align-items:center;min-height:var(--fh);padding:0 24px}
.list .head{background:var(--field);font:500 12px/1.3 var(--ui);letter-spacing:.08em;text-transform:uppercase;color:var(--ink)}   /* the head is a thick line: THE line's own colour as a surface, ink on it (the chrome pass, Sep 3). On the hub the ground was --tint so a --panel head stood out; on the app the ground IS --panel and the head vanished into it. 18% was too close to the 14% ground (Chris); 22% (--outside) is the conservative alternative if this is too strong */
.list .head .c{white-space:nowrap}   /* a label never breaks ("NUMB / ER") — the list's one rule until its sitting (Sep 3) */
.list .c.fit{white-space:nowrap}   /* a fit column (an auto track: Number, Total) never breaks — amounts and numbers are one piece */
.list .head.title{display:flex;justify-content:space-between;color:var(--ink)}
/* the head's one non-heading thing, the DOOR: a nav link at the right in --acting with the arrow — the same language on every table that doubles as a door (Clients, Invoices, Referrals → Settings) */
.list .head.title a{color:var(--acting)}
.list .head.title a::after{content:"\a0▸"}
.list .head.title a:hover{color:var(--ink)}
.list .row{position:relative;border-top:var(--line);font-size:15px;color:var(--ink);padding-top:10px;padding-bottom:10px}   /* 48 when one line; a per-currency stack or a detail line may run taller */
.list .row.link:hover{background:var(--panel)}
.list .row.link>a.c{color:inherit;text-decoration:none}
.list .row.link>a.c::after{content:"";position:absolute;inset:0}   /* the first cell is the row's link, stretched over the row — no form ever nests in an anchor */
.list .row .c>a{color:inherit;text-decoration:none}   /* a cell's HONEST link (ruled Sep 7, People: the name to the person, the email a mailto:) — the row's text, underlined on hover; no row link, no row hover */
.list .row .c>a:hover{text-decoration:underline}
.list .c{min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;line-height:1.4}   /* NEVER WRAPS (ruled Sep 6): an ellipsis in every table, the row stays 48 — if it feels constraining, reconsider what is in the table, not the rule */
.list .c.m{font-family:var(--mono);font-size:14px;letter-spacing:0;text-transform:none}
.list .row .c.m{color:var(--ink)}
.list .c.r{text-align:right;justify-self:end;padding-right:calc(2*var(--u))}   /* a right-aligned number breathes: 2u on its right, keyed to the class, never measured — harmless when the row stacks (the chrome pass, Sep 3) */
.list .c.q,.list .row .c.q{color:var(--ink3)}
.list .c .l{display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.list .c .l+.l{margin-top:2px}
.list .c .l.d{font-size:13px;color:var(--ink3)}   /* a detail line under the text — the activity's diff, the send's recipients */
.list .row .c.m .l.d{font-family:var(--mono);font-size:12px}
/* ROWS CARRY NO FILL (ruled Sep 6): two registers in a status cell — ink for facts (Draft · Sent Sep 5 · Paid Sep 2 · Marked paid by check), red for late and only late (Overdue 21 days) — and a third, CLOSED: a paid row's status muted; a voided row muted in EVERY column, amount included, on the PAGE's ground — a hollow row. Urgency comes from the BLOCK (being in Needs you), never a fill; a future due date earns no colour. Yellow means "where you are" (rail, tab) and never appears in a list — the Sep 3 mark under the "now" states is retired (the palette rule is three colours, one job each). */
.list .st.late{color:var(--late)}
.list .row.q{background:var(--panel)}
.list .row.q .c,.list .row.q .c.m,.list .row.q .st.late{color:var(--ink3)}
.list .tag{display:inline-flex;align-items:center;height:22px;padding:0 8px;margin-left:10px;border:var(--line);font:500 11px/1 var(--ui);letter-spacing:.08em;text-transform:uppercase;color:var(--ink2);white-space:nowrap;vertical-align:middle}   /* a small cell of the line — square, not a pill: the system has one shape */
.list .act,.list .ord{position:relative;z-index:1;justify-self:end;white-space:nowrap}
.list .ord{justify-self:start;display:flex;gap:6px}
.list .act form,.list .ord form{display:inline;margin:0}
.list .act a,.list .act button{font:500 12px/1 var(--ui);letter-spacing:.08em;text-transform:uppercase;color:var(--acting);background:none;border:0;padding:0;cursor:pointer;text-decoration:none}
.list .act a:hover,.list .act button:hover{color:var(--ink)}
.list .ord button{font:inherit;background:none;border:0;padding:0;color:var(--ink3);cursor:pointer}
.list .ord button:hover{color:var(--ink)}
.list .empty{padding:14px 24px;border-top:var(--line);color:var(--ink3)}
.list>.row:first-child{border-top:0}   /* a headless list (Home's birthday row, Sep 6): the box drew the top */
/* THE EMPTY STATE (ruled Sep 6): the table's place holds ONE ROW — the bar's height, drawing its top — and in it the bar's box construction: a 48 box of the line, `+` in its own cell, the noun in the next, caps voice; hover = panel + ink (a chrome cell on the tint). Inside the box (Home's clients) the row also draws its left, like every cell there. */
.emptyrow{display:flex;align-items:center;height:var(--bar);padding:0 24px;border-top:var(--line)}
.box>.emptyrow{border-left:var(--line)}
.emptyrow .start{display:flex;height:var(--fh);border:var(--line);color:var(--ink);font:500 12px/1 var(--ui);letter-spacing:.08em;text-transform:uppercase;text-decoration:none;transition:background-color .15s ease,color .15s ease}
.emptyrow .start span{display:flex;align-items:center;padding:0 24px}
.emptyrow .start .plus{padding:0 18px;font-size:18px;letter-spacing:0;color:var(--acting)}
.emptyrow .start span+span{border-left:var(--line)}
.emptyrow .start:hover{background:var(--panel);color:var(--ink)}
.list .row .form{display:flex;align-items:center;gap:12px;margin:0}
.list .row .form-actions{margin:0}
.list .row .form .save{font:500 12px/1 var(--ui);letter-spacing:.08em;text-transform:uppercase;color:var(--acting);background:none;border:0;padding:0;cursor:pointer}
.list .row .form .save:hover{color:var(--ink)}
/* the check: the platform's checkbox wearing the token (FLAGGED — "checkbox styling should become the line" is on the silent list) */
.check{display:inline-flex;align-items:center;gap:10px;font-size:14px;color:var(--ink);cursor:pointer}
.check input{margin:0;width:16px;height:16px;accent-color:var(--acting);cursor:pointer}
.card dl.facts{margin:0;display:grid;grid-template-columns:auto 1fr;column-gap:16px;row-gap:4px;font-size:14px}
.card dl.facts dt{color:var(--ink2)}.card dl.facts dd{margin:0;color:var(--ink)}
.card>.sec>p{margin:0 0 calc(2*var(--u))}
/* a list page: the title in the display face, then the box */
.card h1.title{font:400 34px/1.1 var(--display);margin:0 0 calc(3*var(--u));color:var(--ink)}
.sec .list+.toggle,.sec .toggle{display:inline-block;margin-top:calc(2*var(--u));font:500 14px/1.4 var(--ui);color:var(--acting);text-decoration:none}   /* a control in the UI face and the acting colour (the show-past toggle), never a mono link */
.sec .toggle:hover{color:var(--ink)}
.sec p.quiet+.list{margin-top:calc(2*var(--u))}
.sec .list+.list,.sec .box+.list{margin-top:calc(3*var(--u))}   /* two lists in a section, or a box over a list (People: the upcoming-birthday CARDS over the table, Sep 7) — rows are 3u apart */
@container card (max-width:640px){
  .list{grid-template-columns:1fr}
  .list .head{display:none}
  .list .row{grid-template-columns:1fr;row-gap:4px;padding-top:12px;padding-bottom:12px}
  .list .c.r{justify-self:start;text-align:left}
  .list .act,.list .ord{justify-self:start}
}

/* ── THE FORM GRAMMAR on the plain pages (the Wave 3 walk, Sep 2): New
   person, Settings ▸ Business / Account / Payments, the reminders rows —
   labeled fields on the grid, sections as rows, the primary in the bar or
   a filled cell at a section's end with its after-line beneath. ── */
.card .go{display:inline-flex;align-items:center;height:var(--fh);padding:0 24px;margin-top:calc(3*var(--u));border:0;background:var(--acting);color:#fff;font:500 12px/1.3 var(--ui);letter-spacing:.08em;text-transform:uppercase;cursor:pointer;text-decoration:none}
.card .go:hover{filter:brightness(1.1)}
.card .go.quiet{background:transparent;border:var(--line);color:var(--ink);margin-top:0}
.card .go.quiet:hover{background:var(--tint);filter:none}
.card .note.after{margin-top:12px;font-size:13px;line-height:1.6;color:var(--ink2)}   /* the quiet line under a button — the consequence, where it belongs */
.card .sec>form{margin:0}
.card .sec>p{margin:0}
.card .sec>h1.title+p{margin-top:12px;color:var(--ink2)}
.card .sec>h1.title+p b{font-weight:500;color:var(--ink)}
.f.pd .pd-in{display:grid;grid-template-columns:minmax(0,2fr) minmax(0,1fr) minmax(0,1fr);gap:var(--gutter)}   /* month · day · year — three fields, one label (no year is the common case) */
.check-field+.check-field{margin-top:calc(2*var(--u))}
.check-field .hint{display:block;margin:6px 0 0 26px;font-size:13px;color:var(--ink3)}
.check{display:inline-flex;align-items:center;gap:10px;font-size:15px;color:var(--ink);cursor:pointer}
.check input{margin:0;width:16px;height:16px;accent-color:var(--acting);cursor:pointer}
.list .check{font-size:14px}
/* the reminders rows: label · the date control at the Issued/Due width · Move · Skip */
.sec.reminder form{margin:0}
.sec.reminder .g.pair{align-items:center}
.sec.reminder .rlabel{font-size:15px;color:var(--ink);min-height:var(--fh);display:flex;align-items:center}
.sec.reminder .racts{display:flex;gap:28px;min-height:var(--fh);align-items:center}
.sec.reminder .act{font:500 14px/1 var(--ui);color:var(--acting);background:none;border:0;padding:0;cursor:pointer}
.sec.reminder .act:hover{color:var(--ink)}
.sec.reminder+.sec.reminder{padding-top:0;border-top:0;margin-top:calc(-1*var(--u))}   /* the two rows read as one block under one heading */

 — the paper's print rules are paper.css's ── */
main.bare{margin:0 auto;max-width:calc(var(--content) + 2*var(--content-edge));font:15px/1.5 var(--ui);color:var(--ink)}
main.bare .paper{min-height:100vh}
@media print{
  body.studio{background:#fff}
  main.bare .paper{min-height:0;padding:0}
  @page{margin:16mm}
}

/* ── slice 10: the invoice page's reminders + hold lines, and the styleguide's
   email section. PLAIN, FLAGGED — no sitting has drawn these. ── */
.hold{display:flex;align-items:center;gap:calc(2*var(--u))}
.hold .form{display:inline}
.hold .form-actions{margin:0;display:inline}
.sec--reminders{padding:calc(3*var(--u)) var(--content-edge)}
.sec--reminders .p-lbl{margin-bottom:var(--u)}
.reminder-choice{display:flex;align-items:flex-end;padding-bottom:calc(1.5*var(--u))}
.styleguide-email h2 small{font-size:12px;letter-spacing:.08em;text-transform:uppercase;color:var(--ink3);margin-left:1ch}
.styleguide-subject{font-family:var(--mono);font-size:13px;margin:0 0 var(--u)}
.styleguide-parts{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:calc(2*var(--u))}
.styleguide-text{margin:0;padding:calc(2*var(--u));background:var(--paper);border:1px solid var(--rule2);font-family:var(--mono);font-size:12px;line-height:1.5;white-space:pre-wrap;overflow-wrap:anywhere}
.styleguide-html{width:100%;min-height:560px;border:1px solid var(--rule2);background:#f4f3ef}
@container (max-width: 640px){.styleguide-parts{grid-template-columns:minmax(0,1fr)}}

/* ═══ HOME (the Home sitting, Sep 3; prototypes/home.html's ── HOME ── block is the spec, each value measured live in Chrome) ═══ */
/* 2× the section's air under the last table — the page's own end, whether or not the footer follows */
.card>.sec:last-child{padding-bottom:calc(8*var(--u))}
/* the page's CLOCK: the period every flow below follows. Three small cells of the line; a choice, so the chosen one is white. */
.clock{display:inline-flex;margin:0 0 calc(3*var(--u))}
.clock a{display:flex;align-items:center;height:32px;padding:0 12px;border:var(--line);border-left:0;font:500 11px/1 var(--ui);letter-spacing:.08em;text-transform:uppercase;color:var(--ink2);transition:background-color .15s ease,color .15s ease}
.clock a:first-child{border-left:var(--line)}
.clock a.on{background:#fff;color:var(--ink)}
.clock a:hover{background:var(--tint);color:var(--ink)}   /* the clock sits on --panel, so the hover goes LIGHTER (the chrome's hover goes to --panel because the chrome sits on --tint — same rule, the other ground) */
.clock a.on:hover{background:#fff}
.home h1.title{margin-bottom:10px}
.home .period{color:var(--ink2)}   /* the studio's day under the name — or the welcome line, while Set up exists */
/* THE H1 BAND ALIGNS WITH THE RAIL BY CONSTRUCTION — TWO RAIL ROWS (ruled Sep 6 evening, shaped live in Chrome). The masthead is 72 + the
   line (main starts at 74); rail items are 48 pitch; the h1 + date band is exactly two rows (74→170; h1 87–124, date 134–157 — 13 above,
   13 below); its bottom rule IS the Clients/Proposals line. NOT derived from --fh: that is 72 (6u); the rail row is 48 by its own rule.
   The book's selector is `.card>.sec:first-child` ("holds on every page, note or no note") and since Sep 8 (ruled: the list pages get
   their own two-row band too) it holds BY CONSTRUCTION — every page's first section IS the band; the one named exception is the
   editors' and send pages' masthead (`.sec--mast`, an explicit class, not a content sniff). The Sep 6 `:has` guard is retired. */
.card>.sec:first-child:not(.sec--mast){box-sizing:border-box;block-size:96px;display:grid;align-content:center;padding-block:0}
/* A list page's clock rides in the band under the h1 — where Home's date line sits (h1 37 + 10 + the clock's 32 = 79 in the 96); FLAGGED
   for the sitting, not ruled. THE TABLE'S HEAD LANDS ON THE THIRD RAIL ROW (ruled Sep 8): the list's section (`tbl`) has no top padding and
   draws no rule of its own — the list's box does (170→172) — and its head is 46 + that 2px line = the 48 pitch (172→218), like the rows
   and Home's Latest row. The birthdays box on People keeps its own section between the band and the table (Home's grammar). */
.card>.sec:first-child>h1.title:has(+.clock){margin-bottom:10px}
.card>.sec:first-child>.clock{margin:0}
.card>.sec.tbl{border-top:0;padding-top:0}
.card>.sec.tbl>.list>.head{min-height:46px}
.card>.sec.tbl>p.quiet{margin:0 0 calc(2*var(--u))}

/* THE LATEST FROM US (ruled Sep 3; reshaped Sep 6; re-done live Sep 6 evening): a collapsed <details> ROW UNDER the h1 band — the THIRD
   RAIL ROW, with its own rule on top (170→218 = the Proposals row; the next section's line is its bottom rule, the Proposals/Invoices line)
   — whose summary IS the headline: kicker · headline · date ON ONE BASELINE (it was vertically centred; the headline sat a pixel low), a
   46 summary + the 2px rule = the 48 pitch, like a rail item. The headline ellipsises; the date is right-aligned with no dot before it (the
   separator after the kicker stays). Hover tints the WHOLE <details> to --tint (the lighter green — NOT --panel, which is the band's own
   ground and reads as no hover), open or closed; the summary's own hover is transparent so there is no seam. Open, the BODY is paper
   (white = the thing you opened), a box of the line inset to the content edge; the row stays chrome; the body's bottom margin is the
   details' PADDING (a margin doesn't take the hover tint, so the last 24px read as a gap). No JS, no seen-state. */
.latest{margin:0 calc(-1*var(--gx) - var(--cardpad));border-top:var(--line);transition:background-color .15s ease}
.latest:hover{background:var(--tint)}
.latest[open]{padding-bottom:24px}
.latest>summary{list-style:none;cursor:pointer;display:grid;grid-template-columns:auto 1fr auto;gap:12px;align-items:baseline;box-sizing:border-box;block-size:46px;padding:0 var(--content-edge);font:500 11px/1 var(--ui);line-height:46px;letter-spacing:.08em;text-transform:uppercase;color:var(--ink3);transition:color .15s ease}
.latest>summary::-webkit-details-marker{display:none}
.latest>summary:hover{background:transparent;color:var(--ink)}
.latest>summary .ttl{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font:400 15px/1.3 var(--ui);letter-spacing:0;text-transform:none;color:var(--ink)}
.latest>summary .ttl::before{content:"·";margin-right:16px;color:var(--ink3)}
.latest>summary .date{font:500 12px/1 var(--mono);letter-spacing:0;text-transform:none;color:var(--ink3);white-space:nowrap;text-align:right}
.latest>.body{--lh:24px;margin:0 var(--content-edge);background:var(--paper);border:var(--line);padding:var(--lh) 24px}
.latest .body p{margin:0;font-size:15px;line-height:var(--lh);color:var(--ink2);max-width:60ch}
.latest .body p+p{margin-top:var(--lh)}
.latest .body p a{color:var(--acting)}
.latest .body p a:hover{color:var(--ink)}

/* set up: label · value · action; the value carries the derived default; two actions read as one phrase */
.setup{--cols:minmax(0,4fr) minmax(0,5fr) auto}
.setup .row .c.v{color:var(--ink2)}
.setup .row .c.v code{font:14px/1 var(--mono);color:var(--ink)}
.setup .act{display:flex;align-items:center;gap:24px}
.setup .act form{display:contents}   /* Keep is a POST: its button sits in the row as the anchor does (measured Sep 3: the form as a flex item put KEEP 5px under CHANGE) */
.setup .head .count{font:400 12px/1.3 var(--ui);letter-spacing:.04em;text-transform:none;color:var(--ink3)}

/* the money: three cells (each draws its LEFT) over the timeline; one box. Each cell: a LABEL (the section's caps voice), the sum, an optional
   detail line — overdue is Outstanding's detail, in the late colour, only when there is any. Sums without cents; the tables carry cents. */
.money{border:var(--line);background:var(--tint)}
.money .sums{display:grid;grid-template-columns:repeat(3,minmax(0,1fr))}
.money .sums .cell{padding:calc(3*var(--u)) 24px;border-left:var(--line);transition:background-color .15s ease}   /* not links — the hover is just the chrome's ease, for the pleasure of it */
.money .sums .cell:first-child{border-left:0}
.money .sums .cell:hover{background:var(--panel)}
.money .h{font:500 11px/1 var(--ui);letter-spacing:.08em;text-transform:uppercase;color:var(--ink3);margin-bottom:10px}
.money .sum{font:500 34px/1.1 var(--mono);color:var(--ink)}
.money .k{margin-top:8px;font-size:13px;color:var(--ink2)}
.money .k.late{color:var(--late)}
.money .good .sum{color:var(--acting)}   /* saved on fees: the good number, in the colour the product acts in */
.money .zero .sum{color:var(--ink3)}
.money figure{margin:0;padding:calc(3*var(--u)) 24px calc(2*var(--u));border-top:var(--line)}
.money figure .fhead{display:flex;justify-content:flex-end;margin-bottom:8px;font:500 11px/1 var(--ui);letter-spacing:.08em;text-transform:uppercase}   /* the chart's head while the target is null: one door, right (FLAGGED — plain) */
.money figure .fhead a{color:var(--acting)}
.money figure .fhead a::after{content:"\a0▸"}
.money figure .fhead a:hover{color:var(--ink)}
.money svg{display:block;width:100%;height:auto}
.money .legend{display:flex;flex-wrap:wrap;gap:12px 24px;margin-top:12px;font:500 11px/1 var(--ui);letter-spacing:.08em;text-transform:uppercase;color:var(--ink3)}
.money .legend i{display:inline-block;width:10px;height:10px;margin-right:6px;vertical-align:-1px}
.money .legend .paid{background:var(--ink)}
.money .legend .invoiced{background:var(--field)}
.money .legend .planned{background:var(--outside)}   /* the third tier, PLANNED (ruled Sep 6: "Expected" was too strong; drafts stay in it — a $10K draft due next month is a fair signal) — recurrences by their Next date and drafts by their due date — the ground's deeper tint, so it reads as "pencilled" */
.money .legend .overdue{background:var(--late)}
@media (max-width:855px){.money .sums{grid-template-columns:1fr}.money .sums .cell{border-left:0;border-top:var(--line)}.money .sums .cell:first-child{border-top:0}}

/* referrals + community (ruled Sep 3; the link re-done live in Chrome, Sep 6 evening — match exactly): ONE 72 row — the sentence left
   (15/1.4, ink, ellipsis), and right-aligned on the row's 24 padding the LINK AS A BOX with a COPY cell, the `+ | Add` construction:
   a 48 box of the line on the tint holding <code> (mono 13 — not 14, so the sentence still fits at the 912 content width: the sentence
   is 532, the box 300, 16 gap) and a COPY cell (its left the line; caps, acting; hover = panel + ink; the copy glyph the app already
   draws). The box's right edge lands on the head's SETTINGS ▸ right edge. TRAPS already found: the app's .c.v carries its own 2px top
   rule (how the old link row drew its line) — left in place it stacks on the box's top border and reads as a 4px rule, so border:0;
   the box is border-box 48 with overflow hidden and its two cells are height:auto / min-height:0 / align-self:stretch — otherwise
   the app's 48-tall .copy overflows a 48-outer box by 2px top and bottom, fattening the top rule and painting over the bottom one. */
.refer{--cols:1fr}
.list.refer .row{display:flex;justify-content:space-between;align-items:center;gap:16px;min-height:72px;padding:0 24px}
.refer .c.n{padding:0}   /* the row carries the inset now (the sentence starts on the head's 24, like REFERRALS above it) */
.refer .figure{font-weight:500;color:var(--ink)}   /* the earned figure: weight, not the highlight (Sep 6: yellow never appears in a list) */
.refer .c.v{display:flex;flex:0 0 auto;align-items:center;gap:24px;white-space:nowrap;background:none;padding:0;border:0}
.refer .c.v code{font:14px/1 var(--mono);color:var(--ink)}   /* community's bare fact (the email you're known by) */
.refer.community .c.v .act{margin-left:auto}   /* the log-in state has one thing in the value cell; it keeps the right edge */
.refer .linkbox{display:inline-flex;box-sizing:border-box;height:48px;overflow:hidden;border:var(--line);background:var(--tint)}
.refer .linkbox code{display:flex;align-items:center;height:auto;min-height:0;align-self:stretch;padding:0 12px;font:13px/1 var(--mono);color:var(--ink)}
.refer button.copy{display:flex;align-items:center;gap:12px;height:auto;min-height:0;align-self:stretch;padding:0 12px;border:0;border-left:var(--line);background:none;cursor:pointer;font:500 12px/1 var(--ui);letter-spacing:.08em;text-transform:uppercase;color:var(--acting);transition:background-color .15s ease,color .15s ease}
.refer button.copy::after{content:"";flex:none;width:16px;height:16px;background:var(--acting);-webkit-mask:url(/images/copy.svg) center/contain no-repeat;mask:url(/images/copy.svg) center/contain no-repeat;transition:background-color .15s ease}   /* the copy glyph, in --acting: this is an action (the footer's icon mechanism) */
.refer button.copy:hover{background:var(--panel);color:var(--ink)}
.refer button.copy:hover::after{background:var(--ink)}
.refer button.copy:disabled{color:var(--acting);cursor:default}   /* COPIED, for a breath, in the same caps voice */
.refer button.copy:disabled::after{-webkit-mask-image:url(/images/check.svg);mask-image:url(/images/check.svg)}   /* COPIED gets a CHECK (ruled Sep 6): the glyph in the same slot becomes a check, same size, no layout shift; the label and the glyph revert together (one disabled state, one timer) — the word is read, the glyph is seen */

/* THE BOX — the list's outer shape for things that aren't lists (the client cells, the email strip): a head row on --field, then cells.
   Border rule, hidden-proof variant: the box draws its top, right and bottom; EVERY row and cell draws its own top and left, the head included —
   so the box's left edge is the cells' own, and a cell that isn't there can never leave a doubled or missing line. */
.box{border:var(--line);border-left:0;background:var(--tint)}
.box>.head{display:flex;justify-content:space-between;align-items:center;min-height:var(--fh);padding:0 24px;border-left:var(--line);background:var(--field);color:var(--ink);font:500 12px/1.3 var(--ui);letter-spacing:.08em;text-transform:uppercase}
.box>.head a{color:var(--acting)}
.box>.head a::after{content:"\a0▸"}
.box>.head a:hover{color:var(--ink)}
/* clients as a GRID OF CELLS, not a table — the hub's room cell (name over the last thing that happened), two across. Same line, a different rhythm. */
.cellgrid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr))}
.cellgrid a{display:grid;grid-template-columns:minmax(0,1fr) auto;column-gap:16px;align-items:center;min-height:var(--fh);padding:10px 24px;border-top:var(--line);border-left:var(--line);transition:background-color .15s ease}
.cellgrid a:hover{background:var(--panel)}
.cellgrid b{font-weight:500;color:var(--ink);display:block}
.cellgrid span{display:block;font-size:13px;color:var(--ink3);margin-top:2px}
.cellgrid .m{font-family:var(--mono);font-size:14px;color:var(--ink);padding-right:calc(2*var(--u))}
.cellgrid a:last-child:nth-child(odd){grid-column:1 / -1}   /* an odd last cell spans the full row; no empty cell is ever drawn (ruled Sep 6: the block reads right at 0, 1, 2, 5, 11) */
@container card (max-width:640px){.cellgrid{grid-template-columns:1fr}}
/* scheduled emails as a STRIP — the money row's shape, three (or four) CARDS across: what fires, when. Re-done live in Chrome (Sep 6
   evening — match exactly): a card is four rows on an 8 gap — .top (WHEN in mono 14/20, the KICKER right in the caps voice) · .d (the
   subject, 15/22 ink, ellipsised) · .to (13/20 quiet, one line each, ellipsised; the amount in mono 13 on its own line) · .n (the
   heads-up, 13/20 quiet, sentence case, pinned to the foot). Three sizes only: 11 caps kicker · 13 quiet · 15 subject; mono is for the
   when-line and money only. Cards run ~205 tall. */
.strip{display:grid;grid-auto-flow:column;grid-auto-columns:minmax(0,1fr)}
.strip>*{display:grid;grid-template-rows:auto auto auto 1fr;gap:8px;min-width:0;padding:20px 24px;border-top:var(--line);border-left:var(--line);transition:background-color .15s ease}
.strip a:hover{background:var(--panel)}
.strip .top{display:flex;justify-content:space-between;align-items:baseline;gap:12px}
.strip .w{font:500 14px/20px var(--mono);color:var(--ink)}
.strip .k{font:500 11px/20px var(--ui);letter-spacing:.08em;text-transform:uppercase;color:var(--ink3);white-space:nowrap}
.strip .d{font:400 15px/22px var(--ui);color:var(--ink);min-width:0;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}
.strip .to{font:400 13px/20px var(--ui);color:var(--ink3);min-width:0}
.strip .to>span{display:block;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}
.strip .to .m{font:500 13px/20px var(--mono)}   /* the amount: mono is for the when-line and money only */
.strip .n{align-self:end;padding-top:4px;font:400 13px/20px var(--ui);color:var(--ink3)}   /* the heads-up: a note on the client email's card, never its own card (ruled Sep 6); date only */
@container card (max-width:640px){.strip{grid-auto-flow:row;grid-auto-columns:auto}}

/* ═══════════════════════════════════════════════════════════════════════════
   SLICE 12a — PROPOSALS: the editor sitting of Sep 4 (prototypes/proposal-edit.html is the spec). The adds and the
   toggles above are the two component rulings that landed once and restyled the invoice editor in passing; below is the
   proposal's own — the block stack as an OUTLINE, the packages one level in, the Image box, the deposit row — plus the
   END ROW (ruled Sep 3, built here for every editor) and the record page's plain state block (FLAGGED).
   ═══════════════════════════════════════════════════════════════════════ */

/* ── THE END ROW (ruled Sep 3; amended Sep 4): the bar's right side reflected at the foot — the bar's height, the 48 acts
   box centred in it, fully framed, on the line under the last section; SAVE · PRIMARY ending on the content's right edge.
   It sits on the panel, so its hover goes to the TINT — the other ground (the bar sits on the tint and hovers to the panel;
   copying its colour made the bottom SAVE look hoverless). ── */
.endrow{margin:0 calc(-1*var(--gx) - var(--cardpad));padding:0 calc(var(--gx) + var(--cardpad));height:var(--bar);border-top:var(--line);display:flex;justify-content:flex-end;align-items:center}
.endrow .acts{display:flex;height:var(--fh);border:var(--line)}
.endrow .acts form{display:contents}
.endrow .btn{height:100%;display:flex;align-items:center;padding:0 24px;border:0;border-left:var(--line);border-radius:0;background:transparent;font:500 12px/1 var(--ui);letter-spacing:.08em;text-transform:uppercase;color:var(--ink);cursor:pointer;text-decoration:none;transition:background-color .15s ease}
.endrow .acts>:first-child,.endrow .acts>form:first-child .btn{border-left:0}
.endrow .btn:hover{background:var(--tint)}
.endrow .btn.primary{background:var(--acting);color:#fff}
.endrow .btn.primary:hover{background:var(--acting);filter:brightness(1.1)}
.card>.sec:has(+.endrow){padding-bottom:calc(4*var(--u))}   /* the last section is not the page's end any more — the row is */

/* ── THE BLOCK STACK AS AN OUTLINE: a block is a <details> — at rest ONE ROW on the line (number · ↑↓ · KIND · its first
   words · Delete), the document's table of contents; open, its fields unfold beneath on the panel ground. name="blk" makes
   the platform keep exactly one open. The open row wears the highlight (where you are); a parent whose child is open is a
   plain row — ONE "here" per surface. The rows are a box of the line, the list component's shape. ── */
.stack{border:var(--line);background:var(--tint)}
.blk{margin:0}
.blk+.blk{border-top:var(--line)}
.blk>summary{display:flex;align-items:center;gap:16px;height:var(--fh);padding:0 24px;list-style:none;cursor:pointer;font:500 12px/1 var(--ui);letter-spacing:.08em;text-transform:uppercase;color:var(--ink2);transition:background-color .15s ease,color .15s ease}
.blk>summary::-webkit-details-marker{display:none}
.blk>summary:hover{background:var(--panel);color:var(--ink)}
.blk[open]>summary,.blk[open]>summary:hover{background:var(--highlight);color:var(--ink)}
.blk[open]:has(> .pkgs > .pkg[open])>summary{background:transparent;color:var(--ink2)}
.blk[open]:has(> .pkgs > .pkg[open])>summary:hover{background:var(--panel)}
.blk>summary .n{font-family:var(--mono);letter-spacing:0;color:var(--ink2);width:2ch;flex:none}
.blk>summary .mv{display:flex;gap:8px;flex:none}
.blk>summary .mv button,.blk>summary .del{font:inherit;background:none;border:0;padding:0;margin:0;color:var(--ink3);cursor:pointer}
.blk>summary .mv button:hover,.blk>summary .del:hover{color:var(--ink)}
.blk>summary .kind{color:var(--ink3);width:9ch;flex:none}
.blk[open]>summary .kind{color:var(--ink2)}
.blk>summary .first{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font:400 15px/1.3 var(--ui);letter-spacing:0;text-transform:none;color:var(--ink)}   /* the block's own words: its heading, or the first line of its text; "Options · 2 packages"; the image's caption */
.blk>summary .first em{font-style:normal;color:var(--ink3)}
.blk>summary .del{letter-spacing:0;text-transform:none;font-size:12px}
.blk>.in{padding:calc(3*var(--u)) 24px calc(4*var(--u));border-top:var(--line);background:var(--panel)}   /* the unfolded block sits on the form ground; its fields are the same windows as everywhere */
.blk .g{row-gap:calc(2*var(--u))}
.blk .adds{margin-top:calc(2*var(--u))}
.f textarea.long{min-height:calc(4*var(--fh))}   /* a Text block's body: four rows at rest (the shell's .body is a reserved word — this is .long) */
/* the Image block's picture: a field-shaped box holding the upload, the line, full width — images are full-width only, to
   start (ruled Sep 4); a 3:1 letterbox as the empty state so the editor doesn't tower. The file input COVERS the box, so a
   file DROPPED on the box lands in the input — the platform's own drop handling, no script; keep this construction. */
.pic{display:flex;align-items:center;justify-content:center;aspect-ratio:3/1;border:var(--line);background:#fff;color:var(--ink3);font:500 11px/1 var(--ui);letter-spacing:.08em;text-transform:uppercase;cursor:pointer;position:relative;overflow:hidden}
.pic:hover{background:var(--highlight);color:var(--ink)}
.pic img{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;display:block}
.pic input[type=file]{position:absolute;inset:0;width:100%;height:100%;margin:0;opacity:0;cursor:pointer}
/* PACKAGES are rows of the SAME stack, one level in — an outline shows depth by indent and numbering (6 · 6.1 · 6.2),
   never by a box inside a box (tried Sep 4: three nested frames). After the last package, + Add a package on the panel:
   the tail of the block's own body, not a row of the outline (on the tint it looked hoverless). */
.pkgs{--step:calc(5*var(--u))}   /* the outline's indent: one step = 40 */
.pkg{border-top:var(--line)}
.pkg>summary{padding-left:calc(24px + var(--step))}
.pkg>summary .n{width:4ch}
.pkg>.in{padding-left:calc(24px + var(--step))}
.addrow{display:flex;align-items:center;height:var(--bar);padding-left:calc(24px + var(--step));border-top:var(--line);background:var(--panel)}
.sub{margin-top:calc(3*var(--u))}
.sub+.sub{border-top:var(--line);padding-top:calc(3*var(--u))}   /* LINES and ADD-ONS are different kinds of thing: the line between them, as between sections */
.sub h3{font:500 11px/1 var(--ui);letter-spacing:.08em;text-transform:uppercase;color:var(--ink3);margin:0 0 calc(2*var(--u))}
.sub .line:first-of-type{padding-top:0}
/* the deposit: Currency 1–3 · Format 4–6 · mode None | Amount | Percent (a three-segment .mode) on 7–9 · its value on
   10–12 (a money field's width — the 4-column version cut off "7,500.00"); the dial 12 under the row above, not a full gap */
.deposit .dial{grid-column:7 / span 6;margin-top:calc(-1*var(--rowgap) + 12px)}
.deposit .dial .check{font-size:14px}

/* ═══ THE PERSON RECORD (the sitting of Sep 7; prototypes/person.html v13 is the spec — its proto layer moved here as the record's rules) ═══ */
/* the h1 band is the APP's: `.card > .sec:first-child > h1.title + .period` — the built band rule (96, grid, centred) applies untouched, so the
   line under it IS the Clients/Proposals line, as on Home. THE BORDER RULE: the band draws no bottom — the thing after it draws its top. */
.rec{background:var(--panel)}
.rec>.sec:first-child{border-bottom:0}
.rec>.sec:first-child+*{border-top:var(--line)}
.rec>.sec:first-child>h1.title{margin-bottom:10px}   /* Home's measure (other cards get 24); with it the h1 sits 87–124 and the line 134–157, as on Home */
.rec .period{color:var(--ink2)}
/* the contact box: Home's .box (head bar, contained, the lighter ground) holding label · value rows — the record grammar (caps label at a
   fixed inset, the value beside it), two columns, 48 rows on the line. Home's cellgrid (bold name over detail) was tried and read bland
   here: that shape is for NAMES; facts want the caps label's contrast. */
.box .facts{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));background:var(--tint)}
.box .facts .fact{display:grid;grid-template-columns:104px 1fr;align-items:center;min-height:48px;padding:0 24px;border-top:var(--line);min-width:0}   /* min-height, not height: a neighbour of a two-line cell stretches with it, so its left rule runs the full row */
.box .facts .fact:nth-child(-n+2){border-top:0}
.box .facts .fact:nth-child(2n){border-left:var(--line)}
.box .facts .fact:nth-child(2n+1){border-left:var(--line)}   /* the app's .box draws no LEFT (its cells do — Home's cellgrid rule); so every first-column cell draws it */
.box .facts .fact:last-child:nth-child(odd){grid-column:1 / -1}   /* an odd last fact spans the row — the cellgrid's rule (ruled Sep 6): no empty cell is ever drawn */
.box .facts .l{font:500 11px var(--ui);letter-spacing:.08em;text-transform:uppercase;color:var(--ink3)}
.box .facts .v{font-size:15px;color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.box .facts .v a{color:var(--acting);text-decoration:underline;text-underline-offset:3px}
.box .facts .v.mono{font:14px var(--mono)}
/* a two-line fact (the address): the row grows to fit; its neighbour grows with it (one grid row). Values still ellipsise per LINE; only
   the address is allowed a second line. BOTH cells of the address's row carry .tall: label and value sit on the FIRST line's baseline,
   at the top of the row — so the neighbour's single line reads as the address's first line, not as centred beside two. */
.box .facts .fact.tall{padding-top:11px;padding-bottom:11px;align-items:first baseline;align-content:start}
.box .facts .fact.tall .v{white-space:normal;line-height:1.45}
/* roles: the tenure column is LEFT-aligned mono, so every start date sits on one edge; a past role (ended, or archived) is muted */
.list .row .c.when{font:14px var(--mono);text-align:left}
.list .row.past .c{color:var(--ink3)}
/* notes: a row that can grow — author · date on a kicker line, the whole body beneath; the Markdown subset's paragraphs 8 apart */
.notes .list .note{padding:14px 24px 16px;border-top:var(--line);background:var(--tint);font-size:15px;line-height:1.5;color:var(--ink)}
.notes .list .note .by{display:flex;gap:12px;align-items:baseline;margin-bottom:4px;font:500 11px var(--ui);letter-spacing:.08em;text-transform:uppercase;color:var(--ink3)}
.notes .list .note .by b{font-weight:500;color:var(--ink2)}
.notes .list .note .by .d{font:13px var(--mono);letter-spacing:0;text-transform:none}
.notes .list .note p{margin:0}
.notes .list .note p+p{margin-top:8px}
.notes .list .note a{color:var(--acting);text-decoration:underline;text-underline-offset:3px}
/* the record's end row: DELETE far left in its own box, EDIT right — distance is the safety (ruled Sep 7, the rule for every record);
   the edit's keeps the app's flex-end (CANCEL · SAVE) */
.endrow.two{justify-content:space-between}
.endrow .acts form{display:contents}
.endrow .btn.danger{color:var(--late)}
.endrow .btn.danger:hover{background:var(--tint);color:var(--ink)}
/* ── EDIT (the person-record sitting, Sep 7): the field grid — label above, white field, the line, 48; two columns; the form bleeds like a
   .sec does (negative margin AND the same padding back), so the .endrow inside it (which bleeds by the app's own rule) lands on the page's
   edges, not twice out ── */
.rec form.edit{margin:0 calc(-1*var(--gx) - var(--cardpad));padding:0 calc(var(--gx) + var(--cardpad));border-top:var(--line)}
.fields{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:24px calc(2*var(--gx));padding:24px 0 32px}
.fields .fld{display:grid;gap:6px;min-width:0;align-content:start}
.fields .fld.wide{grid-column:1/-1}
.fields label{font:500 13px/1.4 var(--ui);color:var(--ink)}
.fields input,.fields select,.fields textarea{box-sizing:border-box;height:48px;padding:0 14px;border:var(--line);background:#fff;font:400 15px var(--ui);color:var(--ink);border-radius:0;width:100%;min-width:0}
.fields textarea{height:100%;min-height:96px;padding:12px 14px;resize:none;line-height:1.5;font-family:var(--ui)}
.fields input:focus,.fields select:focus,.fields textarea:focus{outline:2px solid var(--ink);outline-offset:-2px}
.fields input::placeholder,.fields textarea::placeholder{color:var(--ink3)}
/* address spans two rows of the grid — it aligns with two fields on the left by construction: the cell spans two grid rows, the textarea
   fills the cell — its bottom edge IS the fourth row's bottom, whatever the labels measure */
.fields .fld.tall{grid-row:span 2;grid-template-rows:auto 1fr}
.fields .fld.tall textarea{height:100%}
/* birthday: month + day (+ optional year) side by side inside one field */
.fields .bday{display:grid;grid-template-columns:minmax(0,1fr) 72px 88px;gap:12px}
/* the select: the platform's arrow replaced by the app's glyph mechanism (the footer's, the copy button's): a masked chevron in --ink2 —
   ONE stroke, 2px like the line, 14 in from the right. A single SVG polyline through `mask`, so the weight matches everything else drawn
   on the page. */
.fields .sel{position:relative;display:block}
.fields select{appearance:none;-webkit-appearance:none;padding-right:44px}
.fields .sel::after{content:"";position:absolute;right:14px;top:50%;width:14px;height:14px;transform:translateY(-50%);background:var(--ink2);pointer-events:none;-webkit-mask:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14 14"><polyline points="2,5 7,10 12,5" fill="none" stroke="black" stroke-width="2" stroke-linecap="square"/></svg>') center/contain no-repeat;mask:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14 14"><polyline points="2,5 7,10 12,5" fill="none" stroke="black" stroke-width="2" stroke-linecap="square"/></svg>') center/contain no-repeat}
/* the box construction: a fixed prefix cell + the input, one line around both */
.fields .box{display:grid;grid-template-columns:auto minmax(0,1fr);border:var(--line);background:#fff;height:48px;box-sizing:border-box}
.fields .box .pre{display:flex;align-items:center;padding:0 12px;border-right:var(--line);background:var(--tint);font:14px var(--mono);color:var(--ink2);white-space:nowrap}
.fields .box input{border:0;height:100%}
.fields .box:focus-within{outline:2px solid var(--ink);outline-offset:-2px}
.fields .box input:focus{outline:none}
/* errors: the FIELD carries it (ruled Sep 1) — label and border in the error colour, the message under the field. Silent in the prototype; the app's rule. */
.fields .fld.err label{color:var(--color-error)}
.fields .fld.err input,.fields .fld.err select,.fields .fld.err textarea,.fields .fld.err .box{border-color:var(--color-error)}
.fields .fld .msg{font:400 12px/1.3 var(--ui);color:var(--color-error)}
/* Add role's Started: month + year side by side in one field (the birthday's grammar without the day) */
.fields .started{display:grid;grid-template-columns:minmax(0,1fr) 88px;gap:12px}
.fields .fld.wide textarea{min-height:calc(4*var(--fh))}   /* Add note's one textarea: four rows at rest (the Text block's measure) */

/* ═══ THE INVOICE RECORD (ruled Sep 8; prototypes/invoice.html v28 is the spec — its proto layer moved here as the record's rules) ═══ */
/* the band's state word — the pay page's vocabulary (Sent · Overdue · Paid · Voided), no detail, at the end of the period line in the
   face's one heavier weight, so it scans; Overdue in the late colour */
.rec>.sec:first-child .period>span{display:inline;font-weight:500;color:var(--ink)}
.rec>.sec:first-child .period .late{color:var(--late)}
/* the STATUS box: the facts grammar grown — a value of PARTS (spans: the overdue count late, the fee note quiet, an amount mono), the
   LINK row always last and full width (`wide`), and the odd fact just before it spanning too (no empty cell) */
.box .facts .fact.wide{grid-column:1 / -1}
.box .facts .fact:nth-last-child(2):nth-child(odd):has(+.wide){grid-column:1 / -1}
.box .facts .v.parts{display:flex;align-items:center;gap:8px;min-width:0}
.box .facts .v.parts>span,.box .facts .v.parts>a>span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.box .facts .v.parts>a{display:flex;align-items:center;gap:8px;min-width:0;overflow:hidden}
.box .facts .v .mono{font:14px var(--mono)}
.box .facts .late{color:var(--late)}
.box .facts .quiet{color:var(--ink3)}
/* the refbox: the studio's own domain, worth the room — the box grows to the cell's edge, then the HANDLE ellipsises: `code` is
   display:block, not flex (a flex box never ellipsises its own text; the ellipsis shows on what gets cut); COPY beside it on the line */
.box .facts .refbox{display:inline-flex;align-items:stretch;border:var(--line);height:36px;box-sizing:border-box;background:var(--panel);max-width:100%;min-width:0}
.box .facts .refbox code{display:block;line-height:32px;padding:0 10px;font:13px/32px var(--mono);color:var(--ink);overflow:hidden;white-space:nowrap;text-overflow:ellipsis;min-width:0}
/* the code cell as a DOOR (Sep 8, the studio's handoff to its portal): a block anchor so the handle still ellipsises; the acting colour on hover — plain, FLAGGED */
.box .facts .refbox a{display:block;min-width:0;overflow:hidden;color:inherit;text-decoration:none}
.box .facts .refbox a:hover code{color:var(--acting);text-decoration:underline}
.box .facts .refbox .copy{display:flex;align-items:center;padding:0 10px;border:0;border-left:var(--line);background:none;font:500 12px/1 var(--ui);letter-spacing:.08em;text-transform:uppercase;color:var(--acting);cursor:pointer;height:auto;min-height:0;white-space:nowrap}
.box .facts .refbox .copy:hover{background:var(--tint);color:var(--ink)}
/* reminders & activity: Home's .list with the title head; the detail cell quiet; the reminder row's SKIP / UNSKIP a quiet caps action at
   the row's end (fine because the row is nothing else); a skipped row stays, muted and struck, its action not */
.list .row .c.x{color:var(--ink3)}
.list .row .c.act{text-align:right}
.list .row .c.act form{display:inline}
.list .row .c.act button{background:none;border:0;padding:0;font:500 11px var(--ui);letter-spacing:.08em;text-transform:uppercase;color:var(--acting);cursor:pointer}
.list .row .c.act button:hover{color:var(--ink)}
.list .row.skipped .c{color:var(--ink3);text-decoration:line-through}
.list .row.skipped .c.act button{text-decoration:none}
/* the paper sits in its own .sec, bleeding, white, edge to edge — the record's last section before the end row */
.rec .sec.sheet{padding:0}
.rec .sec.sheet .paper{margin:0}
