@sobree/core 0.1.12 → 0.1.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Formatting value-types: borders, shading, and table-style conditional
3
+ * formatting.
4
+ *
5
+ * Split out from `types.ts` (the core AST module) as a dependency-free
6
+ * LEAF — none of these reference the recursive `Block` document graph, so
7
+ * they import nothing from `types.ts`. Keeping them here avoids a circular
8
+ * dependency: `types.ts` imports + re-exports them, so consumers still get
9
+ * every AST type from `./types`.
10
+ */
11
+ export interface BorderSpec {
12
+ style: "single" | "double" | "dashed" | "dotted" | "thick" | "none";
13
+ /** Eighths of a point (Word's `w:sz`). */
14
+ sizeEighthsOfPt: number;
15
+ /** `#rrggbb` or `auto`. */
16
+ color: string;
17
+ /** Twips of clear space between border and text. */
18
+ spaceTwips?: number;
19
+ }
20
+ export interface Shading {
21
+ /** Pattern (`clear`, `pct10`, `solid`, …). Most highlights are `clear`. */
22
+ pattern: string;
23
+ /** Background `#rrggbb` or `auto`. */
24
+ fill: string;
25
+ /** Pattern foreground `#rrggbb` or `auto`. */
26
+ color?: string;
27
+ }
28
+ export interface TableBorders {
29
+ top?: BorderSpec;
30
+ right?: BorderSpec;
31
+ bottom?: BorderSpec;
32
+ left?: BorderSpec;
33
+ insideH?: BorderSpec;
34
+ insideV?: BorderSpec;
35
+ }
36
+ export interface TableCellBorders {
37
+ top?: BorderSpec;
38
+ right?: BorderSpec;
39
+ bottom?: BorderSpec;
40
+ left?: BorderSpec;
41
+ }
42
+ /** Default cell padding (`<w:tblCellMar>` / `<w:tcMar>`), in twips. An
43
+ * absent side falls back to the renderer's Word default. */
44
+ export interface TableCellMargins {
45
+ topTwips?: number;
46
+ rightTwips?: number;
47
+ bottomTwips?: number;
48
+ leftTwips?: number;
49
+ }
50
+ /** `<w:tblLook>` flags. A flag absent ⇒ that conditional format is OFF. */
51
+ export interface TableLook {
52
+ firstRow?: boolean;
53
+ lastRow?: boolean;
54
+ firstColumn?: boolean;
55
+ lastColumn?: boolean;
56
+ /** Row (horizontal) banding active. */
57
+ hBand?: boolean;
58
+ /** Column (vertical) banding active. */
59
+ vBand?: boolean;
60
+ }
61
+ /**
62
+ * A table style's conditional-format regions (`<w:tblStylePr w:type>`).
63
+ * Each names a slice of the table whose cells get extra formatting when
64
+ * the table's `<w:tblLook>` enables it. Resolution precedence (low→high,
65
+ * ECMA-376 §17.7.6): wholeTable → vBands → hBands → first/last column →
66
+ * first/last row → corner cells, then direct cell formatting wins.
67
+ */
68
+ export type TableConditionalType = "firstRow" | "lastRow" | "firstCol" | "lastCol" | "band1Horz" | "band2Horz" | "band1Vert" | "band2Vert" | "nwCell" | "neCell" | "swCell" | "seCell";
69
+ /** The formatting one region (or the whole-table base) contributes. */
70
+ export interface TableStyleCellFormat {
71
+ shading?: Shading;
72
+ borders?: TableCellBorders;
73
+ }
74
+ /**
75
+ * A `<w:style w:type="table">` definition: whole-table base formatting +
76
+ * per-region conditional formatting + band sizes. Resolved per cell at
77
+ * render time against the table's `look`.
78
+ */
79
+ export interface TableStyleDefinition {
80
+ /** Whole-table borders (`<w:tblBorders>` — incl. `insideH`/`insideV`). */
81
+ borders?: TableBorders;
82
+ /** Whole-table base cell shading. */
83
+ shading?: Shading;
84
+ /** Rows per horizontal band (`<w:tblStyleRowBandSize>`, default 1). */
85
+ rowBandSize?: number;
86
+ /** Columns per vertical band (`<w:tblStyleColBandSize>`, default 1). */
87
+ colBandSize?: number;
88
+ /** Whole-table default cell padding (`<w:tblCellMar>` in the style). */
89
+ cellMargins?: TableCellMargins;
90
+ conditional?: Partial<Record<TableConditionalType, TableStyleCellFormat>>;
91
+ }
@@ -0,0 +1,24 @@
1
+ import { NamedStyle, TableLook, TableStyleCellFormat, TableStyleDefinition } from './types';
2
+ /** Logical position of a cell within its table (left/top edge of the
3
+ * cell when it spans multiple grid columns / rows). */
4
+ export interface TableCellPosition {
5
+ rowIndex: number;
6
+ colIndex: number;
7
+ rowCount: number;
8
+ colCount: number;
9
+ }
10
+ /**
11
+ * Merge a table style up its `basedOn` chain into one definition. Base
12
+ * ancestor first, the named style last so it wins. Sub-objects merge
13
+ * field-by-field (a child that sets only `firstRow` keeps the parent's
14
+ * `band1Horz`). Returns `null` if the style id is unknown or carries no
15
+ * table formatting.
16
+ */
17
+ export declare function resolveTableStyle(styles: readonly NamedStyle[], styleId: string | undefined): TableStyleDefinition | null;
18
+ /**
19
+ * Resolve the conditional cell formatting (shading + per-side border
20
+ * overrides) for one cell, gated by the table's `look`. Base whole-table
21
+ * borders are NOT included (the renderer draws those at table level);
22
+ * base shading IS, since nothing else applies it.
23
+ */
24
+ export declare function resolveTableCellFormat(def: TableStyleDefinition, look: TableLook, pos: TableCellPosition): TableStyleCellFormat;
@@ -1,21 +1,6 @@
1
+ import { BorderSpec, Shading, TableBorders, TableCellBorders, TableCellMargins, TableLook, TableStyleDefinition } from './formatting.types';
1
2
  import { FontDeclaration as _FontDeclaration } from '../fonts/types';
2
- /**
3
- * Sobree's internal document model.
4
- *
5
- * Every node here maps 1-to-1 to an OOXML construct so serialisation to
6
- * `.docx` is mechanical (no decisions, no lossy translation). The names
7
- * are JS-friendly — `Paragraph`, `RunProperties`, etc. — rather than
8
- * `<w:p>`, `<w:rPr>` directly, but the shapes line up.
9
- *
10
- * Conventions:
11
- * - All numeric measurements that originate in OOXML keep their native
12
- * unit, suffixed in the field name: `wTwips`, `sizeHalfPt`, `widthEmu`.
13
- * - All node objects are JSON-clean (no functions, classes, or
14
- * references) so they cross any wire (Yjs sync messages, MCP,
15
- * postMessage) untouched.
16
- * - Optional fields are `?:` — absence means "not set", not "default".
17
- * Defaults are applied at render time from the document's styles.
18
- */
3
+ export type { BorderSpec, Shading, TableBorders, TableCellBorders, TableCellMargins, TableConditionalType, TableLook, TableStyleCellFormat, TableStyleDefinition, } from './formatting.types';
19
4
  export interface SobreeDocument {
20
5
  /** Top-level body content, in document order. */
21
6
  body: Block[];
@@ -676,23 +661,6 @@ export interface ParagraphBorders {
676
661
  left?: BorderSpec;
677
662
  between?: BorderSpec;
678
663
  }
679
- export interface BorderSpec {
680
- style: "single" | "double" | "dashed" | "dotted" | "thick" | "none";
681
- /** Eighths of a point (Word's `w:sz`). */
682
- sizeEighthsOfPt: number;
683
- /** `#rrggbb` or `auto`. */
684
- color: string;
685
- /** Twips of clear space between border and text. */
686
- spaceTwips?: number;
687
- }
688
- export interface Shading {
689
- /** Pattern (`clear`, `pct10`, `solid`, …). Most highlights are `clear`. */
690
- pattern: string;
691
- /** Background `#rrggbb` or `auto`. */
692
- fill: string;
693
- /** Pattern foreground `#rrggbb` or `auto`. */
694
- color?: string;
695
- }
696
664
  export interface Table {
697
665
  kind: "table";
698
666
  /** Column widths in twips. Length = number of columns. */
@@ -707,14 +675,14 @@ export interface TableProperties {
707
675
  borders?: TableBorders;
708
676
  /** Style reference (e.g. "TableGrid"). */
709
677
  styleId?: string;
710
- }
711
- export interface TableBorders {
712
- top?: BorderSpec;
713
- right?: BorderSpec;
714
- bottom?: BorderSpec;
715
- left?: BorderSpec;
716
- insideH?: BorderSpec;
717
- insideV?: BorderSpec;
678
+ /** `<w:tblLook>` — which of the table style's conditional formats are
679
+ * active (first row / column, last row / column, row / column
680
+ * banding). Gates {@link TableStyleDefinition} resolution. */
681
+ look?: TableLook;
682
+ /** `<w:tblCellMar>` — default inner padding for every cell (the table's
683
+ * own value wins over the style's). Word's stock default is ~108 twips
684
+ * left / right and 0 top / bottom when omitted. */
685
+ cellMargins?: TableCellMargins;
718
686
  }
719
687
  export interface TableRow {
720
688
  cells: TableCell[];
@@ -732,12 +700,6 @@ export interface TableCell {
732
700
  /** Cell content — paragraphs and (rare) nested tables. */
733
701
  content: Block[];
734
702
  }
735
- export interface TableCellBorders {
736
- top?: BorderSpec;
737
- right?: BorderSpec;
738
- bottom?: BorderSpec;
739
- left?: BorderSpec;
740
- }
741
703
  export interface SectionProperties {
742
704
  pageSize: PageSize;
743
705
  pageMargins: PageMargins;
@@ -826,6 +788,9 @@ export interface NamedStyle {
826
788
  paragraphDefaults?: ParagraphProperties;
827
789
  /** Default table properties (only for table styles). */
828
790
  tableDefaults?: TableProperties;
791
+ /** Table-style borders + conditional formatting (only for table
792
+ * styles). Resolved per cell at render time. */
793
+ tableStyle?: TableStyleDefinition;
829
794
  }
830
795
  export interface NumberingDefinition {
831
796
  /** `numId` referenced from `ParagraphProperties.numbering`. */
@@ -0,0 +1,6 @@
1
+ import { TableStyleDefinition } from '../../doc/types';
2
+ /**
3
+ * Parse a table-style `<w:style>` element into a TableStyleDefinition, or
4
+ * `null` if it carries no table-specific formatting worth keeping.
5
+ */
6
+ export declare function readTableStyle(styleEl: Element): TableStyleDefinition | null;
@@ -0,0 +1,8 @@
1
+ import { TableBorders, TableCellBorders, TableCellMargins } from '../../doc/types';
2
+ /** Read `<w:tblBorders>` (outer edges + `insideH`/`insideV`). */
3
+ export declare function readTableBorders(el: Element): TableBorders | null;
4
+ /** Read `<w:tcBorders>` (a cell's four edges). */
5
+ export declare function readCellBorders(el: Element): TableCellBorders | null;
6
+ /** Read `<w:tblCellMar>` / `<w:tcMar>` — per-side cell padding in twips.
7
+ * Each side child (`<w:top>`, `<w:left>`, …) carries `w:w` (twips). */
8
+ export declare function readCellMargins(el: Element): TableCellMargins | null;
package/dist/index.css CHANGED
@@ -1 +1 @@
1
- .sobree-viewport{position:relative;overflow:hidden;overscroll-behavior:contain;touch-action:none;background:#ececee}.sobree-viewport__stage{position:absolute;top:0;left:0;transform-origin:0 0}.sobree-viewport__stage.is-gesturing,.sobree-viewport__stage.is-animating{will-change:transform}.sobree-viewport__stage.is-animating{transition:transform .32s cubic-bezier(.2,.7,.2,1)}.sobree-viewport__slot{display:block}.sobree-editor{position:relative;outline:none}.sobree-editor>:first-child{margin-top:0}.sobree-editor p,.sobree-editor h1,.sobree-editor h2,.sobree-editor h3,.sobree-editor h4,.sobree-editor h5,.sobree-editor h6,.sobree-editor ul,.sobree-editor ol,.sobree-editor li,.sobree-editor blockquote,.sobree-editor pre{margin:0;padding:0}.sobree-editor ul,.sobree-editor ol{padding-left:1.5em}.sobree-editor li.sobree-li-continuation{list-style-type:none}.sobree-editor li.sobree-li-continuation::marker{content:""}.sobree-editor .sobree-fragment-continued{text-align-last:justify}.sobree-editor .sobree-footnote-ref a{color:inherit;text-decoration:none}.sobree-editor .sobree-footnote-ref a:hover{text-decoration:underline}.sobree-editor .sobree-footnotes{margin-top:2em;padding-top:.5em;border-top:1pt solid currentColor;font-size:.85em}.sobree-editor .sobree-footnotes__list{padding-left:1.5em}.sobree-editor .sobree-footnotes__item{margin:.25em 0}.sobree-editor ins.sobree-revision-ins{text-decoration:underline}.sobree-editor del.sobree-revision-del{text-decoration:line-through}.sobree-editor .sobree-revision-format{text-decoration:underline dashed var(--sobree-format-revision-color, currentColor);text-underline-offset:3px}.sobree-editor [data-block-revision=ins]:after,.sobree-editor [data-block-revision=del]:after{content:" ¶";color:var(--sobree-block-revision-color, currentColor);opacity:.65;font-weight:600;-webkit-user-select:none;user-select:none}.sobree-editor [data-block-revision=del]:after{text-decoration:line-through}.sobree-editor .sobree-comment-range{background:var(--sobree-comment-range-bg, rgba(255, 217, 0, .25));border-bottom:1px dotted var(--sobree-comment-range-border, rgba(180, 130, 0, .5))}.sobree-editor .sobree-comment-ref{display:inline;font-size:.85em;margin:0 .1em}.sobree-editor .sobree-comment-ref a{color:inherit;text-decoration:none}.sobree-editor .sobree-comment-ref a:hover{filter:brightness(.7)}.sobree-editor h1,.sobree-editor h2,.sobree-editor h3,.sobree-editor h4,.sobree-editor h5,.sobree-editor h6{font-size:inherit;font-weight:inherit}.sobree-editor table{border-collapse:collapse;width:100%;position:relative}.sobree-editor th,.sobree-editor td{border:none;padding:0 .08in;vertical-align:top;transition:border-color .12s ease}.sobree-editor .sobree-section-break{display:flex;align-items:center;gap:8px;margin:8px 0;color:var(--fg-subtle, #7c7764);font-size:11px;letter-spacing:.04em;text-transform:uppercase;-webkit-user-select:none;user-select:none}.sobree-editor .sobree-section-break--continuous{visibility:hidden;height:0;margin:0;padding:0;border:none;overflow:hidden;font-size:0;line-height:0}.sobree-editor .sobree-section-break:before,.sobree-editor .sobree-section-break:after{content:"";flex:1;border-top:1px dashed var(--border, #dedbd0)}.sobree-editor .sobree-section-break__label{flex:none;padding:0 6px;background:var(--bg-elevated, #fff)}.sobree-editor .sobree-textbox-frame p{line-height:1.2}.sobree-editor .paper-content p,.sobree-editor .paper-content li,.sobree-editor .paper-header p,.sobree-editor .paper-header li,.sobree-editor .paper-footer p,.sobree-editor .paper-footer li,.sobree-editor .sobree-textbox-frame p{white-space:pre-wrap}.sobree-editor .sobree-section-trailer-empty{height:0;line-height:0;font-size:0;margin:0;padding:0;overflow:hidden}.sobree-editor .sobree-textbox-frame--placeholder{border:1px solid var(--border, #c8c4b8)}.sobree-editor .sobree-textbox-frame--placeholder.sobree-textbox-frame--filled{border:none;z-index:-1}.sobree-editor img.is-selected{outline:2px solid var(--sobree-primary, #d4521f);outline-offset:2px}.sobree-image-resize-handle{position:absolute;width:16px;height:16px;background:var(--sobree-primary, #d4521f);border:2px solid #fff;border-radius:3px;cursor:nwse-resize;z-index:1000;-webkit-user-select:none;user-select:none}.paper-stack{display:flex;flex-direction:column;padding:48px;gap:28px;outline:none}.paper-row{display:flex;flex-direction:row;align-items:flex-start;gap:24px}.paper{position:relative;background:#fff;border:1px solid rgba(0,0,0,.3);box-shadow:0 1px 2px #00000014,0 18px 60px #0000001f;padding-top:var(--margin-top, 25mm);padding-right:var(--margin-right, 20mm);padding-bottom:var(--margin-bottom, 25mm);padding-left:var(--margin-left, 20mm);overflow:hidden;flex:none}.paper-header,.paper-footer{position:absolute;left:var(--margin-left, 20mm);right:var(--margin-right, 20mm);font-size:10pt;color:#555;white-space:pre-wrap}.paper-header{top:0;min-height:var(--margin-top, 25mm);padding-top:var(--header-offset-mm, 12.7mm);padding-bottom:4mm;border-bottom:1px dashed transparent}.paper-footer{bottom:0;min-height:var(--margin-bottom, 25mm);padding-top:4mm;text-align:center;border-top:1px dashed transparent}.paper-anchors{position:absolute;top:0;right:0;bottom:0;left:0;pointer-events:none;isolation:isolate;z-index:1}.paper-anchors.is-empty{display:none}.paper-anchors-behind{position:absolute;top:0;right:0;bottom:0;left:0;pointer-events:none;isolation:isolate;z-index:0}.paper-anchors-behind.is-empty{display:none}.paper-zone-anchors{position:absolute;top:0;right:0;bottom:0;left:0;pointer-events:none;isolation:isolate;z-index:2}.paper-zone-anchors.is-empty{display:none}.paper-anchor{position:absolute;box-sizing:border-box;overflow:hidden}.paper-header>p,.paper-footer>p,.paper-header>ul,.paper-header>ol,.paper-footer>ul,.paper-footer>ol{margin:0}.paper-footnotes{position:absolute;left:var(--margin-left, 20mm);right:var(--margin-right, 20mm);bottom:var(--margin-bottom, 25mm);font-size:.85em;padding-top:.5em;border-top:1pt solid currentColor;background:#fffffff5;z-index:1;max-height:40%;overflow:hidden}.paper-footnotes.is-empty{display:none}.paper-comments{flex:0 0 70mm;max-width:70mm;font-size:.85em;padding:0 .5em;align-self:stretch;overflow-y:auto}.paper-comments.is-empty{display:none}.paper-footnotes .sobree-footnotes__list{margin:0;padding-left:1.5em}.paper-footnotes .sobree-footnotes__item{margin:.25em 0}.paper-content a{color:inherit;text-decoration:none}.paper-content{position:relative;height:100%;min-height:100px;display:flow-root}.paper-content td p:not([style*=line-height]),.paper-content td li:not([style*=line-height]),.paper-content th p:not([style*=line-height]),.paper-content th li:not([style*=line-height]){line-height:1}.paper-content td p:not([style*=margin]),.paper-content th p:not([style*=margin]){margin:0}.paper-content .sobree-hang>li{list-style:none}.paper-content .sobree-hang>li:before{display:inline-block;box-sizing:border-box;width:var(--sobree-list-hang, 0);margin-left:calc(-1 * var(--sobree-list-hang, 0));white-space:nowrap;color:var(--sobree-marker-color, currentColor);font-family:var(--sobree-marker-font, inherit);font-size:var(--sobree-marker-size, inherit)}.paper-content .sobree-hang.lst-bullet>li:before{content:var(--sobree-bullet, "•")}.paper-content .sobree-hang.lst-decimal>li:before{content:var(--mk-pre, "") counter(list-item,decimal) var(--mk-suf, ".")}.paper-content .sobree-hang.lst-decimal-zero>li:before{content:var(--mk-pre, "") counter(list-item,decimal-leading-zero) var(--mk-suf, ".")}.paper-content .sobree-hang.lst-lower-latin>li:before{content:var(--mk-pre, "") counter(list-item,lower-latin) var(--mk-suf, ".")}.paper-content .sobree-hang.lst-upper-latin>li:before{content:var(--mk-pre, "") counter(list-item,upper-latin) var(--mk-suf, ".")}.paper-content .sobree-hang.lst-lower-roman>li:before{content:var(--mk-pre, "") counter(list-item,lower-roman) var(--mk-suf, ".")}.paper-content .sobree-hang.lst-upper-roman>li:before{content:var(--mk-pre, "") counter(list-item,upper-roman) var(--mk-suf, ".")}.paper-content .sobree-tab-spread{display:flex;justify-content:space-between;align-items:baseline;gap:1em;white-space:nowrap}.paper-content .sobree-tab-spread .sobree-tab-spread__before,.paper-content .sobree-tab-spread .sobree-tab-spread__after{white-space:pre-wrap;min-width:0}.paper-content table.sobree-table-bordered td,.paper-content table.sobree-table-bordered th{border:var(--table-cell-border, none);padding:0 4px}.paper-content .sobree-cols-unequal{display:flex;align-items:flex-start}.paper-content .sobree-cols-unequal .sobree-col{flex:0 0 auto}.paper-stack .paper-content,.paper-stack .paper-header,.paper-stack .paper-footer{transition:opacity .2s ease}.paper-stack.is-zone-editing .paper-content,.paper-stack.is-zone-editing .paper-header,.paper-stack.is-zone-editing .paper-footer{opacity:.2}.paper-stack.is-zone-editing .paper-header[contenteditable=true],.paper-stack.is-zone-editing .paper-footer[contenteditable=true]{opacity:1}.paper-header[contenteditable=true],.paper-footer[contenteditable=true]{outline:2px dotted var(--primary, #c96f22);outline-offset:4px;background:var(--primary-soft, #fdf6ee);color:var(--fg-strong, #14130f);border-radius:2px}
1
+ .sobree-viewport{position:relative;overflow:hidden;overscroll-behavior:contain;touch-action:none;background:#ececee}.sobree-viewport__stage{position:absolute;top:0;left:0;transform-origin:0 0}.sobree-viewport__stage.is-gesturing,.sobree-viewport__stage.is-animating{will-change:transform}.sobree-viewport__stage.is-animating{transition:transform .32s cubic-bezier(.2,.7,.2,1)}.sobree-viewport__slot{display:block}.sobree-editor{position:relative;outline:none}.sobree-editor>:first-child{margin-top:0}.sobree-editor p,.sobree-editor h1,.sobree-editor h2,.sobree-editor h3,.sobree-editor h4,.sobree-editor h5,.sobree-editor h6,.sobree-editor ul,.sobree-editor ol,.sobree-editor li,.sobree-editor blockquote,.sobree-editor pre{margin:0;padding:0}.sobree-editor ul,.sobree-editor ol{padding-left:1.5em}.sobree-editor li.sobree-li-continuation{list-style-type:none}.sobree-editor li.sobree-li-continuation::marker{content:""}.sobree-editor .sobree-fragment-continued{text-align-last:justify}.sobree-editor .sobree-footnote-ref a{color:inherit;text-decoration:none}.sobree-editor .sobree-footnote-ref a:hover{text-decoration:underline}.sobree-editor .sobree-footnotes{margin-top:2em;padding-top:.5em;border-top:1pt solid currentColor;font-size:.85em}.sobree-editor .sobree-footnotes__list{padding-left:1.5em}.sobree-editor .sobree-footnotes__item{margin:.25em 0}.sobree-editor ins.sobree-revision-ins{text-decoration:underline}.sobree-editor del.sobree-revision-del{text-decoration:line-through}.sobree-editor .sobree-revision-format{text-decoration:underline dashed var(--sobree-format-revision-color, currentColor);text-underline-offset:3px}.sobree-editor [data-block-revision=ins]:after,.sobree-editor [data-block-revision=del]:after{content:" ¶";color:var(--sobree-block-revision-color, currentColor);opacity:.65;font-weight:600;-webkit-user-select:none;user-select:none}.sobree-editor [data-block-revision=del]:after{text-decoration:line-through}.sobree-editor .sobree-comment-range{background:var(--sobree-comment-range-bg, rgba(255, 217, 0, .25));border-bottom:1px dotted var(--sobree-comment-range-border, rgba(180, 130, 0, .5))}.sobree-editor .sobree-comment-ref{display:inline;font-size:.85em;margin:0 .1em}.sobree-editor .sobree-comment-ref a{color:inherit;text-decoration:none}.sobree-editor .sobree-comment-ref a:hover{filter:brightness(.7)}.sobree-editor h1,.sobree-editor h2,.sobree-editor h3,.sobree-editor h4,.sobree-editor h5,.sobree-editor h6{font-size:inherit;font-weight:inherit}.sobree-editor table{border-collapse:collapse;width:100%;position:relative}.sobree-editor th,.sobree-editor td{border:none;padding:0 .08in;vertical-align:top;transition:border-color .12s ease}.sobree-editor .sobree-section-break{display:flex;align-items:center;gap:8px;margin:8px 0;color:var(--fg-subtle, #7c7764);font-size:11px;letter-spacing:.04em;text-transform:uppercase;-webkit-user-select:none;user-select:none}.sobree-editor .sobree-section-break--continuous{visibility:hidden;height:0;margin:0;padding:0;border:none;overflow:hidden;font-size:0;line-height:0}.sobree-editor .sobree-section-break:before,.sobree-editor .sobree-section-break:after{content:"";flex:1;border-top:1px dashed var(--border, #dedbd0)}.sobree-editor .sobree-section-break__label{flex:none;padding:0 6px;background:var(--bg-elevated, #fff)}.sobree-editor .sobree-textbox-frame p{line-height:1.2}.sobree-editor .paper-content p,.sobree-editor .paper-content li,.sobree-editor .paper-header p,.sobree-editor .paper-header li,.sobree-editor .paper-footer p,.sobree-editor .paper-footer li,.sobree-editor .sobree-textbox-frame p{white-space:pre-wrap}.sobree-editor .sobree-section-trailer-empty{height:0;line-height:0;font-size:0;margin:0;padding:0;overflow:hidden}.sobree-editor .sobree-textbox-frame--placeholder{border:1px solid var(--border, #c8c4b8)}.sobree-editor .sobree-textbox-frame--placeholder.sobree-textbox-frame--filled{border:none;z-index:-1}.sobree-editor img.is-selected{outline:2px solid var(--sobree-primary, #d4521f);outline-offset:2px}.sobree-image-resize-handle{position:absolute;width:16px;height:16px;background:var(--sobree-primary, #d4521f);border:2px solid #fff;border-radius:3px;cursor:nwse-resize;z-index:1000;-webkit-user-select:none;user-select:none}.paper-stack{display:flex;flex-direction:column;padding:48px;gap:28px;outline:none}.paper-row{display:flex;flex-direction:row;align-items:flex-start;gap:24px}.paper{position:relative;background:#fff;border:1px solid rgba(0,0,0,.3);box-shadow:0 1px 2px #00000014,0 18px 60px #0000001f;padding-top:var(--margin-top, 25mm);padding-right:var(--margin-right, 20mm);padding-bottom:var(--margin-bottom, 25mm);padding-left:var(--margin-left, 20mm);overflow:hidden;flex:none}.paper-header,.paper-footer{position:absolute;left:var(--margin-left, 20mm);right:var(--margin-right, 20mm);font-size:10pt;color:#555;white-space:pre-wrap}.paper-header{top:0;min-height:var(--margin-top, 25mm);padding-top:var(--header-offset-mm, 12.7mm);padding-bottom:4mm;border-bottom:1px dashed transparent}.paper-footer{bottom:0;min-height:var(--margin-bottom, 25mm);padding-top:4mm;text-align:center;border-top:1px dashed transparent}.paper-anchors{position:absolute;top:0;right:0;bottom:0;left:0;pointer-events:none;isolation:isolate;z-index:1}.paper-anchors.is-empty{display:none}.paper-anchors-behind{position:absolute;top:0;right:0;bottom:0;left:0;pointer-events:none;isolation:isolate;z-index:0}.paper-anchors-behind.is-empty{display:none}.paper-zone-anchors{position:absolute;top:0;right:0;bottom:0;left:0;pointer-events:none;isolation:isolate;z-index:2}.paper-zone-anchors.is-empty{display:none}.paper-anchor{position:absolute;box-sizing:border-box;overflow:hidden}.paper-header>p,.paper-footer>p,.paper-header>ul,.paper-header>ol,.paper-footer>ul,.paper-footer>ol{margin:0}.paper-footnotes{position:absolute;left:var(--margin-left, 20mm);right:var(--margin-right, 20mm);bottom:var(--margin-bottom, 25mm);font-size:.85em;padding-top:.5em;border-top:1pt solid currentColor;background:#fffffff5;z-index:1;max-height:40%;overflow:hidden}.paper-footnotes.is-empty{display:none}.paper-comments{flex:0 0 70mm;max-width:70mm;font-size:.85em;padding:0 .5em;align-self:stretch;overflow-y:auto}.paper-comments.is-empty{display:none}.paper-footnotes .sobree-footnotes__list{margin:0;padding-left:1.5em}.paper-footnotes .sobree-footnotes__item{margin:.25em 0}.paper-content a{color:inherit;text-decoration:none}.paper-content{position:relative;height:100%;min-height:100px;display:flow-root}.paper-content td p:not([style*=line-height]),.paper-content td li:not([style*=line-height]),.paper-content th p:not([style*=line-height]),.paper-content th li:not([style*=line-height]){line-height:1}.paper-content td p:not([style*=margin]),.paper-content th p:not([style*=margin]){margin:0}.paper-content .sobree-hang>li{list-style:none}.paper-content .sobree-hang>li:before{display:inline-block;box-sizing:border-box;width:var(--sobree-list-hang, 0);margin-left:calc(-1 * var(--sobree-list-hang, 0));white-space:nowrap;color:var(--sobree-marker-color, currentColor);font-family:var(--sobree-marker-font, inherit);font-size:var(--sobree-marker-size, inherit)}.paper-content .sobree-hang.lst-bullet>li:before{content:var(--sobree-bullet, "•")}.paper-content .sobree-hang.lst-decimal>li:before{content:var(--mk-pre, "") counter(list-item,decimal) var(--mk-suf, ".")}.paper-content .sobree-hang.lst-decimal-zero>li:before{content:var(--mk-pre, "") counter(list-item,decimal-leading-zero) var(--mk-suf, ".")}.paper-content .sobree-hang.lst-lower-latin>li:before{content:var(--mk-pre, "") counter(list-item,lower-latin) var(--mk-suf, ".")}.paper-content .sobree-hang.lst-upper-latin>li:before{content:var(--mk-pre, "") counter(list-item,upper-latin) var(--mk-suf, ".")}.paper-content .sobree-hang.lst-lower-roman>li:before{content:var(--mk-pre, "") counter(list-item,lower-roman) var(--mk-suf, ".")}.paper-content .sobree-hang.lst-upper-roman>li:before{content:var(--mk-pre, "") counter(list-item,upper-roman) var(--mk-suf, ".")}.paper-content .sobree-tab-spread{display:flex;justify-content:space-between;align-items:baseline;gap:1em;white-space:nowrap}.paper-content .sobree-tab-spread .sobree-tab-spread__before,.paper-content .sobree-tab-spread .sobree-tab-spread__after{white-space:pre-wrap;min-width:0}.paper-content table.sobree-table-bordered td,.paper-content table.sobree-table-bordered th{padding:0 4px}.paper-content .sobree-cols-unequal{display:flex;align-items:flex-start}.paper-content .sobree-cols-unequal .sobree-col{flex:0 0 auto}.paper-stack .paper-content,.paper-stack .paper-header,.paper-stack .paper-footer{transition:opacity .2s ease}.paper-stack.is-zone-editing .paper-content,.paper-stack.is-zone-editing .paper-header,.paper-stack.is-zone-editing .paper-footer{opacity:.2}.paper-stack.is-zone-editing .paper-header[contenteditable=true],.paper-stack.is-zone-editing .paper-footer[contenteditable=true]{opacity:1}.paper-header[contenteditable=true],.paper-footer[contenteditable=true]{outline:2px dotted var(--primary, #c96f22);outline-offset:4px;background:var(--primary-soft, #fdf6ee);color:var(--fg-strong, #14130f);border-radius:2px}