From f1d673302f5d7258fece283ae7a5838aa6f2d12c Mon Sep 17 00:00:00 2001 From: righ Date: Sun, 4 Oct 2026 04:47:20 +0900 Subject: [PATCH 1/6] feat: autoExpand option to grow the sheet on paste / autofill overflow `options.autoExpand` ('none' | 'vertical' | 'horizontal' | 'both', default 'none') lets a paste or an autofill that runs past the last row/column append the missing rows/columns instead of clipping them, capped by limits.maxRows / maxCols. - engine: Sheet.autoExpand; copy / copyAsync / move / writeRawCellMatrix and Autofill grow the sheet first. New BATCH history so the growth and the write undo/redo as one step; the growth is rolled back if the operation is refused (e.g. by a merge). - react-core: while dragging the autofill handle, ghost rows/columns are rendered past the edge (as real table rows/cells, so sticky headers stay) so the drag can reach cells that don't exist yet. A paste that grew the sheet scrolls the pasted corner into view. - fix: releasing an autofill drag over a ScrollHandle submitted the fill twice (two undo steps); StoreObserver's mouseup is now the only submitter. - docs, storybook story (Restriction/AutoExpand), jest + e2e specs. Co-Authored-By: Claude Opus 5.5 --- e2e/auto-expand.spec.ts | 91 +++++ .../src/content/docs/api-reference/props.mdx | 22 ++ packages/engine/src/auto-expand.spec.ts | 138 ++++++++ packages/engine/src/index.ts | 2 + packages/engine/src/lib/autofill.ts | 16 +- packages/engine/src/lib/book.ts | 2 + packages/engine/src/lib/sheet.ts | 323 ++++++++++++++++-- packages/engine/src/types.ts | 22 ++ .../react-core/src/components/GridSheet.tsx | 10 +- .../src/components/ScrollHandle.tsx | 40 ++- .../src/components/StoreObserver.tsx | 5 +- .../react-core/src/components/Tabular.tsx | 103 +++++- packages/react-core/src/store/actions.ts | 25 +- packages/react-core/src/types.ts | 10 +- .../restriction/autoExpand.stories.tsx | 60 ++++ packages/web/src/index.ts | 1 + packages/web/src/lib/virtualization.ts | 45 ++- packages/web/src/styles/minified.ts | 4 +- packages/web/src/styles/root.min.css | 2 +- packages/web/src/styles/tabular.less | 24 +- 20 files changed, 886 insertions(+), 59 deletions(-) create mode 100644 e2e/auto-expand.spec.ts create mode 100644 packages/engine/src/auto-expand.spec.ts create mode 100644 packages/storybook/stories/restriction/autoExpand.stories.tsx diff --git a/e2e/auto-expand.spec.ts b/e2e/auto-expand.spec.ts new file mode 100644 index 00000000..26473fd6 --- /dev/null +++ b/e2e/auto-expand.spec.ts @@ -0,0 +1,91 @@ +import { test, expect } from '@playwright/test'; +import { copy, ctrl, drag, go, paste } from './utils'; + +const STORY = 'restriction-autoexpand--auto-expand'; + +const setMode = async (page: any, mode: string) => { + await page.locator(`.mode-selector input[value='${mode}']`).check(); +}; + +const text = (page: any, address: string) => + page.locator(`[data-address='${address}'] .gs-cell-rendered`).textContent(); + +test('paste past the edge grows the sheet, and undo shrinks it back', async ({ page }) => { + await go(page, STORY); + await setMode(page, 'both'); + + // A1:C3 pasted at C4 on a 5x4 sheet needs rows 4..6 and cols C..E. + await drag(page, 'A1', 'C3'); + await copy(page); + await page.locator("[data-address='C4']").click(); + await paste(page); + + expect(await text(page, 'E6')).toBe('z'); + expect(await text(page, 'C4')).toBe('1'); + // The grown rows/cols would sit off-screen, so the grid scrolls the pasted corner into view. + await expect(page.locator("[data-address='E6']")).toBeInViewport(); + + await ctrl(page, 'z'); + await expect(page.locator("[data-address='E6']")).toHaveCount(0); + await expect(page.locator("[data-address='A6']")).toHaveCount(0); + expect(await text(page, 'C4')).toBe(''); +}); + +test("paste past the edge is clipped with 'none'", async ({ page }) => { + await go(page, STORY); + await setMode(page, 'none'); + + await drag(page, 'A1', 'C3'); + await copy(page); + await page.locator("[data-address='C4']").click(); + await paste(page); + + expect(await text(page, 'D5')).toBe('b'); + await expect(page.locator("[data-address='A6']")).toHaveCount(0); + // Nothing grew, so nothing scrolled. + expect(await page.locator('.gs-tabular').evaluate((el) => el.scrollTop)).toBe(0); + await expect(page.locator("[data-address='E1']")).toHaveCount(0); +}); + +test("'vertical' grows rows only", async ({ page }) => { + await go(page, STORY); + await setMode(page, 'vertical'); + + await drag(page, 'A1', 'C3'); + await copy(page); + await page.locator("[data-address='C4']").click(); + await paste(page); + + expect(await text(page, 'D6')).toBe('c'); + await expect(page.locator("[data-address='E1']")).toHaveCount(0); +}); + +test('autofill dragged past the last row fills the ghost rows', async ({ page }) => { + await go(page, STORY); + await setMode(page, 'vertical'); + + // Select the 1,2,3 series and drag its fill handle below the grid. + await drag(page, 'A1', 'A3'); + const handle = page.locator("[data-address='A3'] .gs-autofill-drag"); + const hb = await handle.boundingBox(); + const tb = await page.locator('.gs-tabular').boundingBox(); + await page.mouse.move(hb!.x + hb!.width / 2, hb!.y + hb!.height / 2); + await page.mouse.down(); + await page.mouse.move(hb!.x + hb!.width / 2, tb!.y + tb!.height - 4, { steps: 5 }); + // Ghost rows appear past the last row while dragging (once it is scrolled into view). + await expect(page.locator('.gs-ghost-row').first()).toBeAttached(); + // Past the bottom edge: the grid auto-scrolls into the ghost area. + await page.mouse.move(hb!.x + hb!.width / 2, tb!.y + tb!.height + 20, { steps: 3 }); + await page.waitForTimeout(800); + await page.mouse.up(); + + await expect(page.locator('.gs-ghost-cell')).toHaveCount(0); + // Rows were appended (5 → more) and the series continued into them. + expect(await text(page, 'A6')).toBe('6'); + // Capped at maxRows (12). + await expect(page.locator("[data-address='A13']")).toHaveCount(0); + + await ctrl(page, 'z'); + await expect(page.locator("[data-address='A6']")).toHaveCount(0); + expect(await text(page, 'A5')).toBe(''); +}); diff --git a/packages/docs/src/content/docs/api-reference/props.mdx b/packages/docs/src/content/docs/api-reference/props.mdx index 83b19497..ca791892 100644 --- a/packages/docs/src/content/docs/api-reference/props.mdx +++ b/packages/docs/src/content/docs/api-reference/props.mdx @@ -30,6 +30,7 @@ The GridSheet component accepts the following props to configure its behavior an | `showFormulaBar` | `boolean` | `true` | Show the formula bar. | | `mode` | `'light' \| 'dark'` | `'light'` | Color mode. | | `eager` | `boolean` | `false` | Opt into eager resolution for this sheet (see below). | +| `autoExpand` | `'none' \| 'vertical' \| 'horizontal' \| 'both'` | `'none'` | Grow the sheet when a paste or autofill runs past the last row/column (see below). | ### `eager` @@ -55,6 +56,27 @@ const all = toValueMatrix(sheet); // off-screen rows come back resolved too If you only need full resolution occasionally (e.g. right before saving) rather than continuously, skip the option and call [`sheet.resolveAll()`](/api-reference/sheet) followed by `await sheet.waitForPending()` on demand — that keeps interactive editing fully virtualized and pays the cost only when you ask for it. +### `autoExpand` + +By default, a paste or an autofill that runs past the sheet's last row or column is clipped: the overflow is dropped. Set `autoExpand` to grow the sheet instead. + +| Value | Behavior | +|-------|----------| +| `'none'` | Clip the overflow (default). | +| `'vertical'` | Append the missing rows. | +| `'horizontal'` | Append the missing columns. | +| `'both'` | Append rows and columns as needed. | + +```tsx + +``` + +- It applies to pasting (copied cells, cut cells, and text/HTML from the clipboard) and to dragging the autofill handle. While dragging, ghost rows/columns are shown past the edge so the drag can reach cells that don't exist yet. +- New rows/columns copy the layout (style, size, policy) of the current last row/column, like inserting rows below the last one. +- Growth is capped by `limits.maxRows` / `limits.maxCols`; anything beyond the limit is still clipped. +- The appended rows/columns and the write are a single undo step. +- Programmatic writes through `sheet.copy()`, `sheet.move()` and `sheet.writeRawCellMatrix()` follow the same setting. + ## Initial Cells The `initialCells` prop defines the starting data and configuration for your spreadsheet. This is where you specify cell values, styles, renderers, policies, and other cell-specific settings. diff --git a/packages/engine/src/auto-expand.spec.ts b/packages/engine/src/auto-expand.spec.ts new file mode 100644 index 00000000..537f3e00 --- /dev/null +++ b/packages/engine/src/auto-expand.spec.ts @@ -0,0 +1,138 @@ +import { Sheet, createRegistry, buildInitialCells, Autofill } from './index'; +import type { AutoExpandType, SheetLimits } from './index'; + +// autoExpand: a paste / autofill that runs past the sheet's edge appends the missing rows/cols +// (per direction, capped by maxRows/maxCols) and the growth undoes together with the write. +describe('autoExpand', () => { + const make = (autoExpand: AutoExpandType, limits?: SheetLimits, numRows = 3, numCols = 3) => { + const registry = createRegistry(); + const cells = buildInitialCells({ + matrices: { + A1: [ + ['a1', 'b1'], + ['a2', 'b2'], + ], + }, + ensured: { numRows, numCols }, + }); + const sheet = new Sheet({ name: 'S', registry, autoExpand, limits }); + sheet.initialize(cells); + registry.contextsBySheetId[sheet.id] = { + store: { sheetReactive: { current: sheet } }, + dispatch: () => {}, + } as any; + return sheet; + }; + const value = (sheet: Sheet, y: number, x: number) => sheet.getCell({ y, x })?.value; + // A1:B2 pasted at C3 needs rows 3..4 and cols 3..4 on a 3x3 sheet. + const pasteA1B2AtC3 = (sheet: Sheet) => + sheet.copy({ src: { top: 1, left: 1, bottom: 2, right: 2 }, dst: { top: 3, left: 3, bottom: 4, right: 4 } }); + + it("clips the overflow with 'none' (default behavior)", () => { + const sheet = make('none'); + pasteA1B2AtC3(sheet); + expect([sheet.numRows, sheet.numCols]).toEqual([3, 3]); + expect(value(sheet, 3, 3)).toBe('a1'); + }); + + it.each<[AutoExpandType, number, number]>([ + ['vertical', 4, 3], + ['horizontal', 3, 4], + ['both', 4, 4], + ])("grows the sheet per direction with '%s'", (mode, rows, cols) => { + const sheet = make(mode); + pasteA1B2AtC3(sheet); + expect([sheet.numRows, sheet.numCols]).toEqual([rows, cols]); + expect(value(sheet, 3, 3)).toBe('a1'); + if (mode === 'both') { + expect(value(sheet, 4, 4)).toBe('b2'); + } + }); + + it('undoes the growth and the paste in one step, and redoes both', () => { + const sheet = make('both'); + const historyCount = sheet.registry.histories.length; + pasteA1B2AtC3(sheet); + expect(sheet.registry.histories.length).toBe(historyCount + 1); + expect(sheet.registry.histories.at(-1)?.operation).toBe('BATCH'); + + sheet.undo(); + expect([sheet.numRows, sheet.numCols]).toEqual([3, 3]); + expect(value(sheet, 3, 3)).toBeFalsy(); + + sheet.redo(); + expect([sheet.numRows, sheet.numCols]).toEqual([4, 4]); + expect(value(sheet, 3, 3)).toBe('a1'); + expect(value(sheet, 4, 4)).toBe('b2'); + }); + + it('records a plain history (no BATCH) when nothing overflows', () => { + const sheet = make('both'); + sheet.copy({ src: { top: 1, left: 1, bottom: 1, right: 1 }, dst: { top: 3, left: 3, bottom: 3, right: 3 } }); + expect(sheet.registry.histories.at(-1)?.operation).toBe('UPDATE'); + }); + + it('stops at maxRows / maxCols and clips the rest', () => { + const sheet = make('both', { maxRows: 4, maxCols: 3 }); + sheet.copy({ src: { top: 1, left: 1, bottom: 2, right: 2 }, dst: { top: 3, left: 2, bottom: 6, right: 3 } }); + expect([sheet.numRows, sheet.numCols]).toEqual([4, 3]); + expect(value(sheet, 4, 3)).toBe('b2'); + }); + + it('grows for an external matrix write (writeRawCellMatrix)', () => { + const sheet = make('vertical'); + sheet.writeRawCellMatrix({ + point: { y: 3, x: 1 }, + matrix: [[{ value: 'x' }], [{ value: 'y' }], [{ value: 'z' }]], + }); + expect(sheet.numRows).toBe(5); + expect(value(sheet, 5, 1)).toBe('z'); + sheet.undo(); + expect(sheet.numRows).toBe(3); + }); + + it('grows for a cut-paste (move)', () => { + const sheet = make('vertical'); + sheet.move({ src: { top: 1, left: 1, bottom: 2, right: 1 }, dst: { top: 3, left: 1, bottom: 4, right: 1 } }); + expect(sheet.numRows).toBe(4); + expect(value(sheet, 4, 1)).toBe('a2'); + sheet.undo(); + expect(sheet.numRows).toBe(3); + expect(value(sheet, 2, 1)).toBe('a2'); + }); + + it('takes the growth back when the operation is refused (move cutting through a merge)', () => { + const sheet = make('vertical'); + sheet.merge({ area: { top: 1, left: 1, bottom: 2, right: 2 } }); + const historyCount = sheet.registry.histories.length; + // The source cuts through the A1:B2 merge, so the move is refused after the sheet grew. + sheet.move({ src: { top: 2, left: 1, bottom: 2, right: 1 }, dst: { top: 3, left: 1, bottom: 5, right: 1 } }); + expect(sheet.numRows).toBe(3); + expect(sheet.registry.histories.length).toBe(historyCount); + }); + + it('grows for an autofill dragged past the last row, clamping to the limit', () => { + const sheet = make('vertical', { maxRows: 6 }); + const store = { + sheetReactive: { current: sheet }, + choosing: { y: 1, x: 1 }, + selectingZone: { startY: 1, startX: 1, endY: 2, endX: 1 }, + }; + new Autofill(store, { y: 10, x: 1 }).applied; + expect(sheet.numRows).toBe(6); + expect(value(sheet, 6, 1)).toBe('a6'); // the series continues a1, a2 → a3..a6 + sheet.undo(); + expect(sheet.numRows).toBe(3); + }); + + it('ignores the column direction for a vertical-only sheet when filling right', () => { + const sheet = make('vertical'); + const store = { + sheetReactive: { current: sheet }, + choosing: { y: 1, x: 1 }, + selectingZone: { startY: 1, startX: 1, endY: 1, endX: 1 }, + }; + new Autofill(store, { y: 1, x: 8 }).applied; + expect(sheet.numCols).toBe(3); + }); +}); diff --git a/packages/engine/src/index.ts b/packages/engine/src/index.ts index a0e85994..f73e9f6d 100644 --- a/packages/engine/src/index.ts +++ b/packages/engine/src/index.ts @@ -90,9 +90,11 @@ export type { HistoryInsertColsType, HistoryRemoveColsType, HistorySortRowsType, + HistoryBatchType, HistoryType, Virtualization, OperatorType, + AutoExpandType, OperationType, Dispatcher, StoreDispatchType, diff --git a/packages/engine/src/lib/autofill.ts b/packages/engine/src/lib/autofill.ts index c2257a0a..9732590f 100644 --- a/packages/engine/src/lib/autofill.ts +++ b/packages/engine/src/lib/autofill.ts @@ -37,6 +37,13 @@ export class Autofill { throw new Error('Sheet is not available'); } this.src = complementSelectingArea(zoneToArea(selectingZone), choosing); + // A drag may point past the sheet's edge (into the auto-expand ghost area). Clamp it to + // what the sheet can actually grow to, so the fill never targets cells that won't exist. + const { numRows, numCols } = sheet.getAutoExpansion({ bottom: draggingTo.y, right: draggingTo.x }); + draggingTo = { + y: Math.min(draggingTo.y, sheet.numRows + numRows), + x: Math.min(draggingTo.x, sheet.numCols + numCols), + }; this.direction = this.suggestDirection(draggingTo); this.dst = this.getDestinationArea(draggingTo); this.sheet = sheet; @@ -106,7 +113,10 @@ export class Autofill { } public get applied(): Sheet { - return this.sheet.update({ diff: this.buildDiff(), operator: 'USER', ...this.reflections }); + // Grow the sheet first (per sheet.autoExpand) when the fill was dragged past its edge. + return this.sheet.withAutoExpand(this.dst, () => + this.sheet.update({ diff: this.buildDiff(), operator: 'USER', ...this.reflections }), + ); } /** Async, progress-reporting apply. Same result as `applied` but time-sliced. */ @@ -114,7 +124,9 @@ export class Autofill { onProgress?: (progress: { done: number; total: number }) => void; yieldControl?: () => Promise | void; }): Promise { - return this.sheet.updateAsync({ diff: this.buildDiff(), operator: 'USER', ...this.reflections, ...opts }); + return this.sheet.withAutoExpandAsync(this.dst, () => + this.sheet.updateAsync({ diff: this.buildDiff(), operator: 'USER', ...this.reflections, ...opts }), + ); } public get wholeArea() { diff --git a/packages/engine/src/lib/book.ts b/packages/engine/src/lib/book.ts index b30bc49e..79f287cd 100644 --- a/packages/engine/src/lib/book.ts +++ b/packages/engine/src/lib/book.ts @@ -95,6 +95,8 @@ export class Registry { historyLimit: number = DEFAULT_HISTORY_LIMIT; lastHistory?: HistoryType; currentHistory?: HistoryType; + /** While non-null, pushed histories are collected here to be recorded as one BATCH. @internal */ + _historyBatch: HistoryType[] | null = null; /** StrictMode guard: Map from action object (identity) to cached reducer result. * Using a Map instead of a single slot allows multiple batched dispatches to coexist. */ _strictModeCache?: Map; diff --git a/packages/engine/src/lib/sheet.ts b/packages/engine/src/lib/sheet.ts index 4f43cfcc..97cf098e 100644 --- a/packages/engine/src/lib/sheet.ts +++ b/packages/engine/src/lib/sheet.ts @@ -19,6 +19,7 @@ import { ShapeType, RectType, OperatorType, + AutoExpandType, OperationType, RawCellType, ExtraPointType, @@ -59,6 +60,7 @@ const shouldTracking = (op: string) => { case 'REMOVE_COLS': case 'MOVE': case 'SORT_ROWS': + case 'BATCH': return true; } return false; @@ -84,6 +86,8 @@ type Props = { registry?: Registry; /** Opt into eager resolution for this sheet (see {@link Sheet.eager}). */ eager?: boolean; + /** Grow the sheet when a paste / autofill overflows it (see {@link Sheet.autoExpand}). */ + autoExpand?: AutoExpandType; }; const noFilter: CellFilter = () => true; @@ -268,6 +272,11 @@ export class Sheet implements UserSheet { * explicitly rather than inferred from the formulas a sheet happens to contain. */ public eager: boolean = false; + /** + * Which way paste (copy / move / writeRawCellMatrix) and autofill may append rows/cols + * when they run past the sheet's edge. 'none' (default) clips the overflow. + */ + public autoExpand: AutoExpandType = 'none'; /** @internal */ public prevName: string = ''; /** @internal */ @@ -341,10 +350,11 @@ export class Sheet implements UserSheet { /** @internal — `_collectMerges` result memoized per sheet version */ private _mergeCache: { version: number; areas: AreaType[] } | null = null; - constructor({ limits = {}, name, registry = createRegistry({}), eager = false }: Props) { + constructor({ limits = {}, name, registry = createRegistry({}), eager = false, autoExpand = 'none' }: Props) { this.idMatrix = []; this.changedTime = Date.now(); this.eager = eager; + this.autoExpand = autoExpand; this._limits = { minRows: limits.minRows ?? 1, maxRows: limits.maxRows ?? -1, @@ -1688,6 +1698,13 @@ export class Sheet implements UserSheet { /** @internal */ private _pushHistory(history: HistoryType) { const book = this.registry; + if (book._historyBatch != null) { + // Collected into one BATCH by _endHistoryBatch(); lastHistory still points at the + // newest child so callers that patch it right after (e.g. insertRows' diff) keep working. + book._historyBatch.push(history); + book.lastHistory = history; + return; + } const strayedHistories = book.histories.splice(book.historyIndex + 1, book.histories.length); strayedHistories.forEach(this._cleanStrayed.bind(this)); book.histories.push(history); @@ -1702,6 +1719,10 @@ export class Sheet implements UserSheet { /** @internal */ private _cleanObsolete(history: HistoryType) { + if (history.operation === 'BATCH') { + history.histories.forEach(this._cleanObsolete.bind(this)); + return; + } if (history.operation === 'REMOVE_ROWS' || history.operation === 'REMOVE_COLS') { history.deleted.forEach((ids) => { ids.forEach((id) => { @@ -1735,6 +1756,10 @@ export class Sheet implements UserSheet { * their registry entries must be deleted to avoid memory leaks. * @internal */ + if (history.operation === 'BATCH') { + history.histories.forEach(this._cleanStrayed.bind(this)); + return; + } if (history.operation === 'INSERT_ROWS' || history.operation === 'INSERT_COLS') { history.idMatrix.forEach((ids) => { ids.forEach((id) => { @@ -1744,6 +1769,138 @@ export class Sheet implements UserSheet { } } + /** + * Start collecting pushed histories so they undo/redo as one step. Returns false when a + * batch is already open (the outer owner closes it), so nested callers must only close + * the batch they opened. + * @internal + */ + private _beginHistoryBatch(): boolean { + if (this.registry._historyBatch != null) { + return false; + } + this.registry._historyBatch = []; + return true; + } + + /** + * Close the batch opened by _beginHistoryBatch() and push it. A single collected history is + * pushed as-is; several become one BATCH carrying the last child's sheet ids / reflections + * (the main operation — expansions are pushed before it and carry none). + * @internal + */ + private _endHistoryBatch(expansionCount = 0) { + const collected = this.registry._historyBatch ?? []; + this.registry._historyBatch = null; + if (collected.length > 0 && collected.length === expansionCount) { + // The operation that needed the room recorded nothing (e.g. refused by a merge or a + // prevention): take the growth back instead of leaving a stray expansion in history. + for (let i = collected.length - 1; i >= 0; i--) { + this._undoHistory(collected[i]); + this._cleanStrayed(collected[i]); + } + this.refresh(true, true); + return; + } + if (collected.length === 0) { + return; + } + if (collected.length === 1) { + this._pushHistory(collected[0]); + return; + } + const main = collected[collected.length - 1]; + this._pushHistory({ + operation: 'BATCH', + srcSheetId: main.srcSheetId, + dstSheetId: main.dstSheetId, + applyed: true, + undoReflection: main.undoReflection, + redoReflection: main.redoReflection, + histories: collected, + }); + } + + /** + * How many rows/cols {@link autoExpand} would append so that `bottom` / `right` fit, + * honoring the expand direction and the maxRows / maxCols limits. + * @internal + */ + public getAutoExpansion({ bottom, right }: { bottom: number; right: number }): { numRows: number; numCols: number } { + const mode = this.autoExpand; + let numRows = 0; + let numCols = 0; + if ((mode === 'vertical' || mode === 'both') && bottom > this.numRows) { + const limit = this.maxNumRows === -1 ? Infinity : this.maxNumRows; + numRows = Math.max(0, Math.min(bottom, limit) - this.numRows); + } + if ((mode === 'horizontal' || mode === 'both') && right > this.numCols) { + const limit = this.maxNumCols === -1 ? Infinity : this.maxNumCols; + numCols = Math.max(0, Math.min(right, limit) - this.numCols); + } + return { numRows, numCols }; + } + + /** + * Append the rows/cols {@link getAutoExpansion} asks for (copying the last row's / column's + * layout, like insertRows/insertCols). Pushes INSERT histories — call inside a history batch + * so they undo together with the operation that needed the room. Returns how many it pushed. + * @internal + */ + private _autoExpandTo(area: { bottom: number; right: number }): number { + const { numRows, numCols } = this.getAutoExpansion(area); + let pushed = 0; + if (numCols > 0) { + this.insertCols({ x: this.numCols + 1, numCols, baseX: this.numCols }); + pushed++; + } + if (numRows > 0) { + this.insertRows({ y: this.numRows + 1, numRows, baseY: this.numRows }); + pushed++; + } + return pushed; + } + + /** + * Run `fn` with the sheet first grown (per {@link autoExpand}) to fit `area`, recording the + * growth and whatever `fn` pushes as a single undo step. + * @internal + */ + public withAutoExpand(area: { bottom: number; right: number }, fn: () => T): T { + const { numRows, numCols } = this.getAutoExpansion(area); + if (numRows === 0 && numCols === 0) { + return fn(); + } + const owner = this._beginHistoryBatch(); + let expansionCount = 0; + try { + expansionCount = this._autoExpandTo(area); + return fn(); + } finally { + if (owner) { + this._endHistoryBatch(expansionCount); + } + } + } + + /** Async counterpart to {@link withAutoExpand}. @internal */ + public async withAutoExpandAsync(area: { bottom: number; right: number }, fn: () => Promise): Promise { + const { numRows, numCols } = this.getAutoExpansion(area); + if (numRows === 0 && numCols === 0) { + return fn(); + } + const owner = this._beginHistoryBatch(); + let expansionCount = 0; + try { + expansionCount = this._autoExpandTo(area); + return await fn(); + } finally { + if (owner) { + this._endHistoryBatch(expansionCount); + } + } + } + /** * Remove an id from registry.data and registry.dependents entirely. * @internal @@ -1792,6 +1949,20 @@ export class Sheet implements UserSheet { operator = 'SYSTEM', undoReflection, redoReflection, + }: MoveProps) { + return this.withAutoExpand(dst, () => + this._move({ srcSheet, src, dst, historicize, operator, undoReflection, redoReflection }), + ); + } + + private _move({ + srcSheet = this, + src, + dst, + historicize = true, + operator = 'SYSTEM', + undoReflection, + redoReflection, }: MoveProps) { const srcSheetRaw = srcSheet.__raw__; // A merge must move whole: refuse a source that cuts through one. @@ -2145,7 +2316,12 @@ export class Sheet implements UserSheet { } /** Build the paste (copy) diff without applying it. Shared by copy()/copyAsync(). @internal */ - private _buildCopyDiff({ srcSheet = this, src, dst, onlyValue = false }: MoveProps & { onlyValue?: boolean }): CellsByAddressType { + private _buildCopyDiff({ + srcSheet = this, + src, + dst, + onlyValue = false, + }: MoveProps & { onlyValue?: boolean }): CellsByAddressType { const isXSheet = srcSheet !== this; const { top: topFrom, left: leftFrom, bottom: bottomFrom, right: rightFrom } = src; const { top: topTo, left: leftTo, bottom: bottomTo, right: rightTo } = dst; @@ -2232,20 +2408,23 @@ export class Sheet implements UserSheet { public copy(props: MoveProps & { onlyValue?: boolean }) { const { operator = 'SYSTEM', undoReflection, redoReflection, dst, onlyValue = false } = props; // A normal paste dissolves the merges it cuts through (values-only keeps the layout). + // Merges only span existing cells, so this is decided before any autoExpand growth. const broken = onlyValue ? {} : this._dissolveMergesDiff(this._mergesBrokenBy(dst, this._collectMerges()), operator); if (broken == null) { return this; } - return this.update({ - diff: { ...broken, ...this._buildCopyDiff(props) }, - partial: false, - operator, - operation: operation.Copy, - undoReflection, - redoReflection, - }); + return this.withAutoExpand(dst, () => + this.update({ + diff: { ...broken, ...this._buildCopyDiff(props) }, + partial: false, + operator, + operation: operation.Copy, + undoReflection, + redoReflection, + }), + ); } /** @@ -2263,6 +2442,17 @@ export class Sheet implements UserSheet { yieldControl?: () => Promise | void; frameBudgetMs?: number; }, + ): Promise { + return this.withAutoExpandAsync(props.dst, () => this._copyAsync(props, opts)); + } + + private async _copyAsync( + props: MoveProps & { onlyValue?: boolean }, + opts: { + onProgress?: (progress: { done: number; total: number }) => void; + yieldControl?: () => Promise | void; + frameBudgetMs?: number; + }, ): Promise { const { srcSheet = this, src, dst, onlyValue = false, operator = 'SYSTEM', undoReflection, redoReflection } = props; const { onProgress, yieldControl, frameBudgetMs = 12 } = opts; @@ -2708,6 +2898,51 @@ export class Sheet implements UserSheet { operator?: OperatorType; undoReflection?: StorePatchType; redoReflection?: StorePatchType; + }) { + const { y: baseY, x: baseX } = point; + // The matrix lands on visible rows only, so the bottom it needs skips filtered rows. + let rowsLeft = matrix.length; + let neededBottom = baseY - 1; + while (rowsLeft > 0 && neededBottom < this.numRows) { + neededBottom++; + if (!this.isRowFiltered(neededBottom)) { + rowsLeft--; + } + } + neededBottom += rowsLeft; + const neededRight = baseX + matrix.reduce((max, row) => Math.max(max, row.length), 0) - 1; + return this.withAutoExpand({ bottom: neededBottom, right: neededRight }, () => + this._writeRawCellMatrix({ + point, + matrix, + updateChangedTime, + historicize, + onlyValue, + operator, + undoReflection, + redoReflection, + }), + ); + } + + private _writeRawCellMatrix({ + point, + matrix, + updateChangedTime, + historicize, + onlyValue, + operator, + undoReflection, + redoReflection, + }: { + point: PointType; + matrix: MatrixType; + updateChangedTime: boolean; + historicize: boolean; + onlyValue: boolean; + operator: OperatorType; + undoReflection?: StorePatchType; + redoReflection?: StorePatchType; }) { const { y: baseY, x: baseX } = point; const diff: CellsByAddressType = {}; @@ -3768,14 +4003,35 @@ export class Sheet implements UserSheet { history.applyed = false; this.registry.currentHistory = this.registry.histories[this.registry.historyIndex]; + if (!this.getSheetBySheetId(history.dstSheetId)) { + return { history: null, newSheet: this.__raw__ }; + } + this._undoHistory(history); + this.refresh(shouldTracking(history.operation), true); + return { + history, + callback: ({ sheetReactive: sheetRef }: { sheetReactive: RefLike }) => { + sheetRef.current?.registry.transmit(history.undoReflection?.transmit); + }, + }; + } + + /** Revert one history entry (recursing into BATCH children). @internal */ + private _undoHistory(history: HistoryType) { const srcSheet = this.getSheetBySheetId(history.srcSheetId); const dstSheet = this.getSheetBySheetId(history.dstSheetId); - if (!dstSheet) { - return { history: null, newSheet: this.__raw__ }; + return; } - switch (history.operation) { + case 'BATCH': { + const children = history.histories; + for (let i = children.length - 1; i >= 0; i--) { + children[i].applyed = false; + this._undoHistory(children[i]); + } + break; + } case 'UPDATE': dstSheet._applyDiff(history.diffBefore, history.partial ?? false); break; @@ -3847,7 +4103,6 @@ export class Sheet implements UserSheet { break; } } - this.refresh(shouldTracking(history.operation), true); if (dstSheet !== this) { dstSheet.addressCaches.clear(); dstSheet.setTotalSize(); @@ -3855,12 +4110,6 @@ export class Sheet implements UserSheet { if (history.operation === 'MOVE' && srcSheet && srcSheet !== dstSheet) { this._xsheetDispatch(srcSheet); } - return { - history, - callback: ({ sheetReactive: sheetRef }: { sheetReactive: RefLike }) => { - sheetRef.current?.registry.transmit(history.undoReflection?.transmit); - }, - }; } public redo() { @@ -3871,14 +4120,35 @@ export class Sheet implements UserSheet { history.applyed = true; this.registry.currentHistory = history; + if (!this.getSheetBySheetId(history.dstSheetId)) { + return { history: null, newSheet: this.__raw__ }; + } + this._redoHistory(history); + this.refresh(shouldTracking(history.operation), true); + return { + history, + callback: ({ sheetReactive: sheetRef }: { sheetReactive: RefLike }) => { + sheetRef.current?.registry.transmit(history.redoReflection?.transmit); + }, + }; + } + + /** Re-apply one history entry (recursing into BATCH children). @internal */ + private _redoHistory(history: HistoryType) { const srcSheet = this.getSheetBySheetId(history.srcSheetId); const dstSheet = this.getSheetBySheetId(history.dstSheetId); - if (!dstSheet) { - return { history: null, newSheet: this.__raw__ }; + return; } - switch (history.operation) { + case 'BATCH': { + const children = history.histories; + for (const child of children) { + child.applyed = true; + this._redoHistory(child); + } + break; + } case 'UPDATE': dstSheet._applyDiff(history.diffAfter, history.partial ?? false); break; @@ -3947,7 +4217,6 @@ export class Sheet implements UserSheet { break; } } - this.refresh(shouldTracking(history.operation), true); if (dstSheet !== this) { dstSheet.addressCaches.clear(); dstSheet.setTotalSize(); @@ -3955,12 +4224,6 @@ export class Sheet implements UserSheet { if (history.operation === 'MOVE' && srcSheet && srcSheet !== dstSheet) { this._xsheetDispatch(srcSheet); } - return { - history, - callback: ({ sheetReactive: sheetRef }: { sheetReactive: RefLike }) => { - sheetRef.current?.registry.transmit(history.redoReflection?.transmit); - }, - }; } /** @internal The history the next undo would apply (without applying it). */ diff --git a/packages/engine/src/types.ts b/packages/engine/src/types.ts index 1dc0108e..8b39462b 100644 --- a/packages/engine/src/types.ts +++ b/packages/engine/src/types.ts @@ -273,7 +273,22 @@ export type HistorySortRowsType = { sortedRowMapping: { [beforeY: number]: number }; }; +/** + * Several histories recorded as one undo/redo step (e.g. the rows/cols an auto-expanding + * paste appended + the paste itself). Undone in reverse order, redone in order. + */ +export type HistoryBatchType = { + operation: 'BATCH'; + srcSheetId: number; + dstSheetId: number; + applyed: boolean; + undoReflection?: StorePatchType; + redoReflection?: StorePatchType; + histories: HistoryType[]; +}; + export type HistoryType = + | HistoryBatchType | HistoryUpdateType | HistoryMoveType | HistoryInsertRowsType @@ -289,6 +304,13 @@ export type Virtualization = { }; export type OperatorType = 'USER' | 'SYSTEM'; +/** + * Which way a paste / autofill may grow the sheet when it runs past the last row/column. + * 'none' (default) clips; 'vertical' appends rows; 'horizontal' appends columns; 'both' does both. + * Growth is capped by the sheet's maxRows / maxCols limits. + */ +export type AutoExpandType = 'none' | 'vertical' | 'horizontal' | 'both'; + export type OperationType = number; /** diff --git a/packages/react-core/src/components/GridSheet.tsx b/packages/react-core/src/components/GridSheet.tsx index 744d6965..5395e4ef 100644 --- a/packages/react-core/src/components/GridSheet.tsx +++ b/packages/react-core/src/components/GridSheet.tsx @@ -117,12 +117,13 @@ export function GridSheet({ sheetName = `Sheet${sheetId}`; console.debug('GridSheet: sheetName is not provided, using default name:', sheetName); } - const { limits, contextMenu, rowMenu, colMenu, eager } = options; + const { limits, contextMenu, rowMenu, colMenu, eager, autoExpand } = options; const sheet = new Sheet({ limits, name: sheetName, registry, eager, + autoExpand, }); sheet.id = sheetId; registry.sheetIdsByName[sheetName] = sheetId; @@ -189,6 +190,13 @@ export function GridSheet({ embedStyle(); }, []); + // autoExpand is read live by paste/autofill, so a changed option applies without a remount. + useEffect(() => { + if (sheetReactive.current) { + sheetReactive.current.autoExpand = options.autoExpand ?? 'none'; + } + }, [options.autoExpand]); + // When sheetWidth/sheetHeight is a string, the sheet stretches to its parent (fill mode) // and the rendered pixel size is measured via ResizeObserver instead of being fixed. const fillWidth = typeof options.sheetWidth === 'string'; diff --git a/packages/react-core/src/components/ScrollHandle.tsx b/packages/react-core/src/components/ScrollHandle.tsx index e840dfbd..d875726c 100644 --- a/packages/react-core/src/components/ScrollHandle.tsx +++ b/packages/react-core/src/components/ScrollHandle.tsx @@ -1,7 +1,7 @@ import type { CSSProperties } from 'react'; import { useEffect, useRef, useContext, useCallback } from 'react'; import { Context } from '../store'; -import { drag, setAutofillDraggingTo, setDragging, submitAutofill } from '../store/actions'; +import { drag, setAutofillDraggingTo, setDragging } from '../store/actions'; import { getAreaInTabular } from '@gridsheet/web'; import { insertRef, isFocus } from '@gridsheet/web'; import { focus } from '@gridsheet/web'; @@ -72,6 +72,29 @@ export function ScrollHandle({ style, horizontal = 0, vertical = 0, className = [sheet, horizontal, vertical, selectingZone], ); + // The autoExpand ghost cell just inside the scrolling edge, if any. getDestEdge finds the edge + // from header cells, which ghost rows/cols don't have. This strip sits on top of the grid, + // so look through it with elementsFromPoint. + const getGhostEdgePoint = useCallback( + (e: React.MouseEvent) => { + const el = tabularRef.current; + if (!el) { + return null; + } + const r = el.getBoundingClientRect(); + const px = horizontal > 0 ? r.right - 2 : Math.min(Math.max(e.clientX, r.left + 1), r.right - 2); + const py = vertical > 0 ? r.bottom - 2 : Math.min(Math.max(e.clientY, r.top + 1), r.bottom - 2); + const ghost = document + .elementsFromPoint(px, py) + .find((node) => (node as HTMLElement).classList?.contains('gs-ghost-cell')) as HTMLElement | undefined; + if (!ghost) { + return null; + } + return { y: Number(ghost.dataset.y), x: Number(ghost.dataset.x) }; + }, + [horizontal, vertical], + ); + const scrollStep = useCallback( (e: React.MouseEvent) => { if (!isScrolling || tabularRef.current === null || !sheet) { @@ -105,7 +128,10 @@ export function ScrollHandle({ style, horizontal = 0, vertical = 0, className = const { x, y } = getDestEdge(e); if (live.autofillDraggingTo) { const { y: curY, x: curX } = live.autofillDraggingTo; - dispatch(setAutofillDraggingTo({ y: y === -1 ? curY : y, x: x === -1 ? curX : x })); + // On an auto-expanding sheet the drag scrolls on into ghost rows/cols past the last + // row/col, which have no header cells for getDestEdge to find — target that cell instead. + const ghostPoint = getGhostEdgePoint(e); + dispatch(setAutofillDraggingTo(ghostPoint ?? { y: y === -1 ? curY : y, x: x === -1 ? curX : x })); } else { if (editingAnywhere) { const newArea = zoneToArea({ ...selectingZone, endY: y, endX: x }); @@ -129,6 +155,7 @@ export function ScrollHandle({ style, horizontal = 0, vertical = 0, className = selectingZone, xSheetFocused, getDestEdge, + getGhostEdgePoint, ], ); @@ -176,10 +203,11 @@ export function ScrollHandle({ style, horizontal = 0, vertical = 0, className = return; } - const { x, y } = getDestEdge(e); if (autofillDraggingTo) { - const { y: curY, x: curX } = autofillDraggingTo; - dispatch(submitAutofill({ y: y === -1 ? curY : y, x: x === -1 ? curX : x })); + // Don't submit here: StoreObserver's capture-phase window mouseup is the sole authority + // for ending a drag and has already submitted the fill. Submitting again (a frame later, + // from this render's stale closure) applied the fill twice — two undo steps, and the + // second targeted the edge computed from header cells, which may not even exist. focus(editorRef.current); } else { if (editingAnywhere) { @@ -188,7 +216,7 @@ export function ScrollHandle({ style, horizontal = 0, vertical = 0, className = } } }, - [autofillDraggingTo, editingAnywhere, getDestEdge], + [autofillDraggingTo, editingAnywhere], ); const handleMouseUpWrapper = useCallback( diff --git a/packages/react-core/src/components/StoreObserver.tsx b/packages/react-core/src/components/StoreObserver.tsx index 9dc75952..5d9ee39e 100644 --- a/packages/react-core/src/components/StoreObserver.tsx +++ b/packages/react-core/src/components/StoreObserver.tsx @@ -98,7 +98,10 @@ export const StoreObserver: FC = ({ el.scrollLeft += dx; const px = Math.min(Math.max(cx, r.left + 1), r.right - 1); const py = Math.min(Math.max(cy, r.top + 1), r.bottom - 1); - const cell = (document.elementFromPoint(px, py) as HTMLElement | null)?.closest('.gs-cell') as HTMLElement | null; + // Ghost cells (autoExpand) past the last row/col carry data-y/x like real cells. + const cell = (document.elementFromPoint(px, py) as HTMLElement | null)?.closest( + '.gs-cell, .gs-ghost-cell', + ) as HTMLElement | null; if (cell) { const y = Number(cell.dataset.y); const x = Number(cell.dataset.x); diff --git a/packages/react-core/src/components/Tabular.tsx b/packages/react-core/src/components/Tabular.tsx index 807df804..5f8b2509 100644 --- a/packages/react-core/src/components/Tabular.tsx +++ b/packages/react-core/src/components/Tabular.tsx @@ -6,14 +6,43 @@ import { HeaderCellLeft } from './HeaderCellLeft'; import { CellStateOverlay } from './CellStateOverlay'; import { Context } from '../store'; -import { choose, select, setContextMenuPosition } from '../store/actions'; +import { choose, select, setAutofillDraggingTo, setContextMenuPosition } from '../store/actions'; import type { RefPaletteType, Virtualization } from '../types'; -import { virtualize, physicalScrollHeight } from '@gridsheet/web'; +import { virtualize, physicalScrollHeight, getGhostCellSize, SCROLL_CAP, range, x2c } from '@gridsheet/web'; import { p2a, stripAddressAbsolute } from '@gridsheet/web'; import { Lexer, stripSheetName } from '@gridsheet/web'; import { ScrollHandle } from './ScrollHandle'; import { preventSafariBounce } from '@gridsheet/web'; +import type { Sheet } from '@gridsheet/web'; + +// Ghost rows/cols kept beyond the drag target, so there is always room to drag (and +// auto-scroll) further past the sheet's edge. +const GHOST_ROWS = 5; +const GHOST_COLS = 2; + +/** + * How many ghost rows/cols to show past the sheet's edge while an autofill is dragged on an + * auto-expanding sheet — enough to reach the current drag target plus some slack, capped by + * the max limits. Zero when the sheet can't grow that way. + */ +const getGhostCount = (sheet: Sheet, draggingTo: { y: number; x: number } | null) => { + const mode = sheet.autoExpand; + if (!draggingTo || mode === 'none') { + return { rows: 0, cols: 0 }; + } + const room = (limit: number, current: number) => (limit === -1 ? Infinity : Math.max(0, limit - current)); + // A capped (remapped) scroll height can't be extended linearly, so very tall sheets get no row ghosts. + const rows = + (mode === 'vertical' || mode === 'both') && sheet.totalHeight <= SCROLL_CAP + ? Math.min(room(sheet.maxNumRows, sheet.numRows), Math.max(0, draggingTo.y - sheet.numRows) + GHOST_ROWS) + : 0; + const cols = + mode === 'horizontal' || mode === 'both' + ? Math.min(room(sheet.maxNumCols, sheet.numCols), Math.max(0, draggingTo.x - sheet.numCols) + GHOST_COLS) + : 0; + return { rows, cols }; +}; export const Tabular = () => { const [palette, setPalette] = useState({}); @@ -32,6 +61,7 @@ export const Tabular = () => { leftHeaderSelecting, topHeaderSelecting, contextMenu, + autofillDraggingTo, } = store; const sheet = sheetReactive.current; @@ -67,6 +97,21 @@ export const Tabular = () => { e.stopPropagation(); }, []); + // Dragging an autofill onto a ghost cell targets that (not yet existing) cell. + const handleGhostMouseEnter = useCallback( + (e: React.MouseEvent) => { + if (!autofillDraggingTo) { + return; + } + const y = Number(e.currentTarget.dataset.y); + const x = Number(e.currentTarget.dataset.x); + if (y !== autofillDraggingTo.y || x !== autofillDraggingTo.x) { + dispatch(setAutofillDraggingTo({ y, x })); + } + }, + [autofillDraggingTo], + ); + const handleScroll = useCallback( (e: React.UIEvent) => { if (sheet) { @@ -219,6 +264,22 @@ export const Tabular = () => { return null; } + const ghostCount = getGhostCount(sheet, autofillDraggingTo); + const ghostSize = getGhostCellSize(sheet); + const ghostHeight = ghostCount.rows * ghostSize.height; + const ghostWidth = ghostCount.cols * ghostSize.width; + const scrollHeight = physicalScrollHeight(sheet); + const ghostXs = ghostCount.cols > 0 ? range(sheet.numCols + 1, sheet.numCols + ghostCount.cols) : []; + // Ghost rows follow the last row, so they only render once the rendered window reaches the + // bottom (offset-based, so trailing filtered — zero-height — rows don't hide them). + const lastRendered = virtualized?.ys?.[virtualized.ys.length - 1]; + const lastRowRendered = lastRendered != null && sheet.getOffsetTop(lastRendered + 1) >= sheet.totalHeight; + const ghostYs = + ghostCount.rows > 0 && lastRowRendered ? range(sheet.numRows + 1, sheet.numRows + ghostCount.rows) : []; + const ghostCell = (y: number, x: number) => ( + + ); + return ( <>
{ style={{ // When a size is explicitly configured, keep that box so a smaller grid can be // centered within it (see .gs-tabular in tabular.less); otherwise shrink to fit. - width: - sheetWidth === -1 ? undefined : fixedWidth ? sheetWidth : Math.min(sheetWidth, sheet.totalWidth), - height: - sheetHeight === -1 ? undefined : fixedHeight ? sheetHeight : Math.min(sheetHeight, sheet.totalHeight), + width: sheetWidth === -1 ? undefined : fixedWidth ? sheetWidth : Math.min(sheetWidth, sheet.totalWidth), + height: sheetHeight === -1 ? undefined : fixedHeight ? sheetHeight : Math.min(sheetHeight, sheet.totalHeight), }} ref={tabularRef} onMouseMove={handleMouseMove} @@ -238,10 +297,11 @@ export const Tabular = () => {
@@ -297,6 +357,15 @@ export const Tabular = () => { className="gs-adjuster gs-adjuster-horizontal gs-adjuster-horizontal-right" style={{ width: virtualized?.adjuster?.right }} > + {ghostXs.map((x) => ( + +
{x2c(x)}
+ + ))} @@ -309,6 +378,9 @@ export const Tabular = () => { {virtualized?.xs?.map((x) => )} + {ghostXs.map((x) => ( + + ))} @@ -320,9 +392,24 @@ export const Tabular = () => { {virtualized?.xs?.map((x) => )} + {ghostXs.map((x) => ghostCell(y, x))} ); })} + {/* autoExpand ghost rows: shown past the last row only while an autofill is dragged. */} + {ghostYs.map((y) => ( + + +
+ {y} +
+ + + {virtualized?.xs?.map((x) => ghostCell(y, x))} + + {ghostXs.map((x) => ghostCell(y, x))} + + ))}
diff --git a/packages/react-core/src/store/actions.ts b/packages/react-core/src/store/actions.ts index 75815345..26060ba6 100644 --- a/packages/react-core/src/store/actions.ts +++ b/packages/react-core/src/store/actions.ts @@ -418,6 +418,17 @@ class CutAction extends CoreAction { } export const cut = new CutAction().bind(); +// When an autoExpand paste grew the sheet, the new rows/cols land off-screen (the viewport +// keeps its size), so the growth would be invisible. Scroll the pasted range's far corner +// into view — after the re-render, so the enlarged scroll area exists. +const revealGrowth = (store: StoreType, sheet: Sheet, before: { numRows: number; numCols: number }, zone: ZoneType) => { + if (sheet.numRows <= before.numRows && sheet.numCols <= before.numCols) { + return; + } + const area = zoneToArea(zone); + requestAnimationFrame(() => smartScroll(sheet, store.tabularRef.current, { y: area.bottom, x: area.right })); +}; + class PasteAction extends CoreAction { mutation = true; reduce(store: StoreType, payload: T): StoreWithCallback { @@ -428,6 +439,7 @@ class PasteAction ext } const { registry } = dstSheet; const { copyingSheetId, copyingZone, cutting } = registry; + const sizeBefore = { numRows: dstSheet.numRows, numCols: dstSheet.numCols }; const srcSheet = dstSheet.getSheetBySheetId(copyingSheetId); let selectingArea = zoneToArea(selectingZone); @@ -485,6 +497,7 @@ class PasteAction ext cutting: false, copyingZone: resetZone, }); + revealGrowth(store, newSheet, sizeBefore, nextSelectingZone); }, }; } @@ -552,9 +565,11 @@ class PasteAction ext // progress bar (paste doesn't change the sheet's dimensions, so the target // selection is known up front). Small pastes stay synchronous. if ((dy + 1) * (dx + 1) > ASYNC_MUTATION_THRESHOLD) { + // The sheet only grows (autoExpand) once the op runs, so clamp to its future size. + const growth = dstSheet.getAutoExpansion(selectingArea); const nextSelectingZone = restrictZone(areaToZone(selectingArea)); - nextSelectingZone.endX = Math.min(nextSelectingZone.endX, dstSheet.numCols); - nextSelectingZone.endY = Math.min(nextSelectingZone.endY, dstSheet.numRows); + nextSelectingZone.endX = Math.min(nextSelectingZone.endX, dstSheet.numCols + growth.numCols); + nextSelectingZone.endY = Math.min(nextSelectingZone.endY, dstSheet.numRows + growth.numRows); return { ...store, pendingAsyncOp: { @@ -565,7 +580,10 @@ class PasteAction ext }), selectingZone: nextSelectingZone, label: 'Pasting', - postCommit: () => registry.transmit({ copyingZone: resetZone }), + postCommit: () => { + registry.transmit({ copyingZone: resetZone }); + revealGrowth(store, dstSheet, sizeBefore, nextSelectingZone); + }, }, }; } @@ -585,6 +603,7 @@ class PasteAction ext registry.transmit({ copyingZone: resetZone, }); + revealGrowth(store, newSheet, sizeBefore, nextSelectingZone); }, }; } diff --git a/packages/react-core/src/types.ts b/packages/react-core/src/types.ts index c3334cd1..62f741a4 100644 --- a/packages/react-core/src/types.ts +++ b/packages/react-core/src/types.ts @@ -48,9 +48,11 @@ export type { HistoryInsertColsType, HistoryRemoveColsType, HistorySortRowsType, + HistoryBatchType, HistoryType, Virtualization, OperatorType, + AutoExpandType, OperationType, Dispatcher, StoreDispatchType, @@ -61,7 +63,7 @@ export type { // React-specific types import type { RefObject, CSSProperties, KeyboardEvent } from 'react'; -import type { Sheet, UserSheet } from '@gridsheet/web'; +import type { Sheet, UserSheet, AutoExpandType } from '@gridsheet/web'; import type { BookType } from '@gridsheet/web'; import type { PolicyType } from '@gridsheet/web'; import type { ContextMenuItemDescriptor, RowMenuItemDescriptor, ColMenuItemDescriptor } from './lib/menu'; @@ -109,6 +111,12 @@ export type OptionsType = { */ eager?: boolean; limits?: SheetLimits; + /** + * Grow the sheet when a paste or autofill runs past the last row/column. + * 'none' (default) clips the overflow; 'vertical' appends rows; 'horizontal' appends + * columns; 'both' appends either. Capped by `limits.maxRows` / `limits.maxCols`. + */ + autoExpand?: AutoExpandType; mode?: ModeType; /** Cell spacing. 'compact' (default) keeps the current metrics; 'comfortable' roomier. */ density?: DensityType; diff --git a/packages/storybook/stories/restriction/autoExpand.stories.tsx b/packages/storybook/stories/restriction/autoExpand.stories.tsx new file mode 100644 index 00000000..b14233ae --- /dev/null +++ b/packages/storybook/stories/restriction/autoExpand.stories.tsx @@ -0,0 +1,60 @@ +import React from 'react'; +import type { Meta, StoryObj } from '@storybook/react'; +import { GridSheet, buildInitialCells, type AutoExpandType } from '@gridsheet/react-core'; + +const meta: Meta = { + title: 'Restriction/AutoExpand', +}; +export default meta; + +const DESCRIPTION = [ + '## Example', + 'With `options.autoExpand`, a paste or an autofill that runs past the last row/column grows the sheet instead of being clipped.', + '## How it works', + "1. `'none'` (default) clips the overflow; `'vertical'` appends rows; `'horizontal'` appends columns; `'both'` appends either.", + '2. While dragging the autofill handle, ghost rows/columns appear past the edge so the drag can reach cells that do not exist yet.', + '3. Growth is capped by `limits.maxRows` / `limits.maxCols` (here 12 rows × 8 columns).', + '4. The added rows/columns and the write undo together in a single step.', +].join('\n\n'); + +const MODES: AutoExpandType[] = ['none', 'vertical', 'horizontal', 'both']; + +const AutoExpandComponent: React.FC = () => { + const [mode, setMode] = React.useState('both'); + return ( +
+
+ {MODES.map((m) => ( + + ))} +
+ +
+ ); +}; + +export const AutoExpand: StoryObj = { + render: () => , + parameters: { + docs: { + description: { + story: DESCRIPTION, + }, + }, + }, +}; diff --git a/packages/web/src/index.ts b/packages/web/src/index.ts index 879adf47..33fb9a78 100644 --- a/packages/web/src/index.ts +++ b/packages/web/src/index.ts @@ -26,6 +26,7 @@ export { virtualize, getAreaInTabular, getCellRectPositions, + getGhostCellSize, getVisibleRowRange, getVisibleColRange, physicalScrollHeight, diff --git a/packages/web/src/lib/virtualization.ts b/packages/web/src/lib/virtualization.ts index 94bb12d0..619a1771 100644 --- a/packages/web/src/lib/virtualization.ts +++ b/packages/web/src/lib/virtualization.ts @@ -45,7 +45,40 @@ export const toPhysicalScrollTop = (sheet: Sheet, virtualTop: number, viewH: num return (virtualTop / virtRange) * physRange; }; -export const getCellRectPositions = (sheet: Sheet, { y, x }: PointType) => { +/** + * Size of one "ghost" row / column past the sheet's edge — what autoExpand would append. + * New rows/cols copy the last row's/column's layout, so the ghost mirrors those sizes. + */ +export const getGhostCellSize = (sheet: Sheet) => { + const lastRow = sheet.getCell({ y: sheet.numRows, x: 0 }, { resolution: 'SYSTEM' }); + const lastCol = sheet.getCell({ y: 0, x: sheet.numCols }, { resolution: 'SYSTEM' }); + return { + height: lastRow?.height || sheet.defaultRowHeight || DEFAULT_HEIGHT, + width: lastCol?.width || sheet.defaultColWidth || DEFAULT_WIDTH, + }; +}; + +type CellRectPositions = { + top: number; + left: number; + bottom: number; + right: number; + width: number; + height: number; +}; + +export const getCellRectPositions = (sheet: Sheet, { y, x }: PointType): CellRectPositions => { + // Past the last row/column (an autofill dragged into the auto-expand ghost area): + // extrapolate with ghost-sized cells after the sheet's total size. + if (y > sheet.numRows || x > sheet.numCols) { + const ghost = getGhostCellSize(sheet); + const inner = getCellRectPositions(sheet, { y: Math.min(y, sheet.numRows), x: Math.min(x, sheet.numCols) }); + const top = y > sheet.numRows ? sheet.totalHeight + (y - sheet.numRows - 1) * ghost.height : inner.top; + const left = x > sheet.numCols ? sheet.totalWidth + (x - sheet.numCols - 1) * ghost.width : inner.left; + const height = y > sheet.numRows ? ghost.height : inner.height; + const width = x > sheet.numCols ? ghost.width : inner.width; + return { top, left, bottom: top + height, right: left + width, width, height }; + } const colCell = sheet.getCell({ y: 0, x }, { resolution: 'SYSTEM' }); const rowCell = sheet.getCell({ y, x: 0 }, { resolution: 'SYSTEM' }); const left = sheet.getSystem({ y: 0, x })?.offsetLeft ?? 0; @@ -98,6 +131,11 @@ export const virtualize = (sheet: Sheet, e: HTMLDivElement | null): Virtualizati break; } } + // Scrolled past the last column (into autoExpand ghost columns): keep the trailing columns + // rendered so the table — and the ghost cells appended to it — stay in place. + if (boundaryLeft === 0 && sheet.numCols > 0) { + boundaryLeft = Math.max(sheet.numCols - OVERSCAN_X, 1); + } // Rows: binary-search the boundaries instead of accumulating heights from row 1. // The old linear scan was O(last-visible-row-index), so scrolling near the bottom // of a tall sheet cost O(numRows) per scroll event (~38ms at 1M rows). getOffsetTop(y) @@ -111,7 +149,10 @@ export const virtualize = (sheet: Sheet, e: HTMLDivElement | null): Virtualizati // First row whose bottom edge passes the viewport top / bottom (binarySearch returns // numRows + 1 when none does, i.e. scrolled past all content / content shorter than view). const topIdx = binarySearch(1, numRows, (y) => cumHeightThrough(y) > top, true); - boundaryTop = topIdx > numRows ? 0 : Math.max(topIdx - OVERSCAN_Y, 1); + // Scrolled past the last row (into autoExpand ghost rows): keep the trailing rows rendered so + // the table — and the ghost rows appended after them — stay in place. + boundaryTop = + topIdx > numRows ? (numRows > 0 ? Math.max(numRows - OVERSCAN_Y, 1) : 0) : Math.max(topIdx - OVERSCAN_Y, 1); // Remap only: the visible block is placed at physical offset adjTop = physTop - top + // before.height (see below). Near the top of a tall (capped) sheet there isn't enough // physical room above the scroll position for the full top overscan, so adjTop would go diff --git a/packages/web/src/styles/minified.ts b/packages/web/src/styles/minified.ts index ff4599b2..2f576a7c 100644 --- a/packages/web/src/styles/minified.ts +++ b/packages/web/src/styles/minified.ts @@ -1,3 +1,3 @@ // pnpm generate-style -export const LAST_MODIFIED = 1790966632; -export const CSS = `.gs-root1{display:inline-block;position:relative;border-spacing:0;width:fit-content;max-width:100%;overflow:auto;font-family:"SF Pro Text","SF Pro Icons","Helvetica Neue",Helvetica,Arial,Meiryo,sans-serif;visibility:hidden;opacity:0}.gs-root1.gs-initialized{visibility:visible;opacity:1;transition:opacity .2s ease-in-out}.gs-root1 .gs-main{flex:1;max-width:100%;overflow:hidden;position:relative;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box}.gs-root1 .gs-resizing{width:100%;height:100%;position:absolute;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 8%,transparent);top:0;left:0;z-index:2}.gs-root1 .gs-line-horizontal{width:100%}.gs-root1 .gs-line-vertical{height:100%}.gs-root1 .gs-line{position:relative;top:0;left:0;border:dotted 1px var(--gs-accent,#2563eb);box-sizing:border-box}.gs-root1 .gs-line span{font-size:10px;padding:3px;background-color:var(--gs-accent,#2563eb);color:#fff;margin:0;position:absolute;top:0;left:0}.gs-root1 .gs-scroll-handle{width:100%;height:100%;cursor:cell}.gs-hidden{visibility:hidden;position:absolute;top:0;left:0;width:0;height:0;overflow:hidden;pointer-events:none;z-index:-1}.gs-fixed{position:fixed;top:0;left:0;z-index:1}:where(.gs-root1[data-mode=light],.gs-editor[data-mode=light]){--gs-fg:#1f2328;--gs-muted-fg:#6b7280;--gs-border:#e3e6ea;--gs-bg:rgba(128, 128, 128, 0.07);--gs-canvas:transparent;--gs-surface:#ffffff;--gs-editor-surface:#ffffff;--gs-header-bg:#f4f5f7;--gs-header-fg:#59616b;--gs-accent:#2563eb}.gs-root1{background-color:var(--gs-bg);color:var(--gs-fg)}.gs-root1 .gs-main{background-color:var(--gs-canvas)}.gs-root1 .gs-tabular{background-color:var(--gs-canvas)}.gs-root1 .gs-sheet-body-data{background-color:var(--gs-surface)}.gs-root1 .gs-formula-bar{background-color:var(--gs-header-bg)}.gs-root1 .gs-formula-bar-editor-inner{color:var(--gs-fg)}.gs-root1 .gs-cell{border:solid 1px var(--gs-border)}.gs-root1 .gs-adjuster{background-color:var(--gs-border)}.gs-root1 .gs-tabular-inner{background-color:var(--gs-border)}.gs-root1 .gs-large-editor textarea{color:var(--gs-fg);caret-color:var(--gs-fg)}.gs-root1 .gs-th{background-color:var(--gs-header-bg);color:var(--gs-header-fg)}.gs-root1 .gs-th-top{border-left:solid 1px var(--gs-border)}.gs-root1 .gs-th-top .gs-th-inner{border-top:solid var(--gs-mx-bt,1px) var(--gs-border)}.gs-root1 .gs-th-left{border-top:solid 1px var(--gs-border)}.gs-root1 .gs-th-left .gs-th-inner{border-left:solid var(--gs-mx-bl,1px) var(--gs-border)}.gs-root1 .gs-search-bar{color:color-mix(in srgb,var(--gs-fg) 40%,transparent)}.gs-root1 .gs-search-bar textarea{color:var(--gs-fg);caret-color:var(--gs-fg)}.gs-editor.gs-editing textarea{caret-color:var(--gs-fg)}.gs-editor.gs-editing .gs-editor-hl{background-color:var(--gs-editor-surface);color:var(--gs-fg)}.gs-editor .gs-editor-options{color:var(--gs-fg);background-color:var(--gs-editor-surface);border:solid 1px var(--gs-border)}:where(.gs-root1[data-mode=dark],.gs-editor[data-mode=dark]){--gs-fg:#e4e6e9;--gs-muted-fg:#8b9096;--gs-border:#2c2f34;--gs-bg:rgba(128, 128, 128, 0.07);--gs-canvas:transparent;--gs-surface:#1c1e21;--gs-editor-surface:#1c1e21;--gs-header-bg:#212327;--gs-header-fg:#a6abb2;--gs-accent:#3b82f6}:where(.gs-root1[data-mode=auto],.gs-editor[data-mode=auto]){--gs-fg:#1f2328;--gs-muted-fg:#6b7280;--gs-border:#e3e6ea;--gs-bg:rgba(128, 128, 128, 0.07);--gs-canvas:transparent;--gs-surface:#ffffff;--gs-editor-surface:#ffffff;--gs-header-bg:#f4f5f7;--gs-header-fg:#59616b;--gs-accent:#2563eb}@media (prefers-color-scheme:dark){:where(.gs-root1[data-mode=auto],.gs-editor[data-mode=auto]){--gs-fg:#e4e6e9;--gs-muted-fg:#8b9096;--gs-border:#2c2f34;--gs-bg:rgba(128, 128, 128, 0.07);--gs-canvas:transparent;--gs-surface:#1c1e21;--gs-editor-surface:#1c1e21;--gs-header-bg:#212327;--gs-header-fg:#a6abb2;--gs-accent:#3b82f6}}:where(.gs-root1[data-mode=inherit-light],.gs-editor[data-mode=inherit-light]){--gs-fg:#1f2328;--gs-muted-fg:#6b7280;--gs-border:#e3e6ea;--gs-bg:rgba(128, 128, 128, 0.07);--gs-surface:#ffffff;--gs-editor-surface:#ffffff;--gs-header-bg:#f4f5f7;--gs-header-fg:#59616b;--gs-accent:#2563eb;--gs-bg:transparent;--gs-canvas:transparent;--gs-surface:transparent;--gs-header-bg:transparent}:where(.gs-root1[data-mode=inherit-dark],.gs-editor[data-mode=inherit-dark]){--gs-fg:#e4e6e9;--gs-muted-fg:#8b9096;--gs-border:#2c2f34;--gs-bg:rgba(128, 128, 128, 0.07);--gs-surface:#1c1e21;--gs-editor-surface:#1c1e21;--gs-header-bg:#212327;--gs-header-fg:#a6abb2;--gs-accent:#3b82f6;--gs-bg:transparent;--gs-canvas:transparent;--gs-surface:transparent;--gs-header-bg:transparent}.gs-root1[data-mode=inherit-dark] .gs-adjuster,.gs-root1[data-mode=inherit-dark] .gs-tabular-inner,.gs-root1[data-mode=inherit-light] .gs-adjuster,.gs-root1[data-mode=inherit-light] .gs-tabular-inner{background-color:transparent}.gs-root1[data-mode=inherit-light] .gs-th{background-color:rgba(128,128,128,.1);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}.gs-root1[data-mode=inherit-dark] .gs-th{background-color:rgba(128,128,128,.1);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}.gs-root1[data-gridlines=horizontal] .gs-cell{border-left-color:transparent;border-right-color:transparent}.gs-root1[data-gridlines=none] .gs-cell{border-color:transparent}.gs-root1[data-density=comfortable] .gs-cell-rendered{padding:0 10px}.gs-cell{transition:border-color .2s ease;padding:0;margin:0;box-sizing:border-box;position:relative;font-size:13px;letter-spacing:1px;line-height:24px;cursor:cell;user-select:none;-webkit-user-select:none;-moz-user-select:none}.gs-cell.gs-copying textarea:focus{outline:solid 1px var(--gs-accent,#2563eb)}.gs-cell.gs-selecting{z-index:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 7%,transparent)}.gs-cell.gs-selecting .gs-cell-label{display:block}.gs-cell.gs-choosing{margin-top:-1px;margin-left:-1px;z-index:1}.gs-cell.gs-choosing.gs-editing{color:transparent}.gs-cell.gs-choosing .gs-cell-label{display:block}.gs-cell.gs-pending .gs-cell-rendered{position:relative;overflow:hidden}.gs-cell.gs-pending .gs-cell-rendered::after{content:'';position:absolute;bottom:0;left:0;height:4px;width:40%;border-radius:1px;background:color-mix(in srgb,var(--gs-accent,#2563eb) 65%,transparent);animation:gs-pending-slide 1.4s ease-in-out infinite}.gs-cell .gs-formula-error-triangle{position:absolute;top:0;right:0;border-top:4px solid rgba(200,0,0,.9);border-right:4px solid rgba(200,0,0,.9);border-bottom:4px solid transparent;border-left:4px solid transparent;z-index:2;cursor:help}.gs-cell .gs-cell-label{font-size:10px;font-weight:500;font-style:normal;font-family:inherit;letter-spacing:.2px;line-height:1.4;position:absolute;top:0;right:0;background-color:var(--gs-accent,#2563eb);color:#fff;padding:1px 5px;border-bottom-left-radius:4px;display:none;opacity:.92}.gs-cell .gs-cell-inner-wrap{width:100%;height:100%;position:absolute;top:0;left:0}.gs-cell .gs-cell-inner{width:100%;height:100%;overflow:hidden;display:flex;box-sizing:border-box;border:none!important}.gs-cell .gs-cell-rendered{overflow:hidden;white-space:pre-wrap;cursor:cell;word-wrap:break-word;word-break:break-all;padding:0 6px;width:100%;height:100%}.gs-cell .gs-cell-rendered>*{position:relative}.gs-cell .gs-cell-rendered>.backface{z-index:0}.gs-cell .gs-autofill-drag{background-color:var(--gs-accent,#2563eb);position:absolute;width:7px;height:7px;bottom:0;right:0;cursor:crosshair;z-index:1}.gs-cell.gs-merged-host{z-index:1}.gs-cell.gs-merged-host.gs-selecting{background-color:transparent}.gs-cell.gs-merged-host.gs-selecting .gs-cell-inner-wrap{background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 7%,transparent)}.gs-cell.gs-merged-covered{z-index:0}.gs-th[data-x="1"] .gs-th-inner-wrap{border-left:none}.gs-th[data-y="1"] .gs-th-inner-wrap{border-top:none}.gs-formula-error-tooltip{position:fixed;background-color:rgba(35,8,8,.94);color:#fff;padding:6px 10px;border-radius:4px;border-left:3px solid rgba(220,50,50,.8);font-size:12px;line-height:1.5;max-width:260px;white-space:pre-wrap;word-break:break-word;box-shadow:0 3px 10px rgba(0,0,0,.4);z-index:100;pointer-events:none;letter-spacing:.3px}.gs-menu-modal{width:100%;height:100vh;z-index:12}.gs-label-input-label{font-size:13px;letter-spacing:1px}.gs-menu-divider{background-color:#aaa;padding:0;margin:5px 0;height:1px;list-style-type:none}.gs-menu-btn{position:absolute;background-color:rgba(128,128,128,.3);border:1px solid #ccc;border-radius:50%;cursor:pointer;font-size:12px;font-weight:700;line-height:1;color:#888;width:18px;height:18px;padding:0;display:flex;align-items:center;justify-content:center;opacity:0;transition:opacity .15s ease;z-index:2}.gs-context-menu{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;opacity:.9;transition:opacity .15s ease}.gs-context-menu:hover{opacity:1}.gs-context-menu .gs-menu-items{color:#555;margin:0;padding:0;min-width:250px}.gs-menu-item{padding:5px 10px;list-style-type:none;display:flex}.gs-menu-item.gs-enabled{cursor:pointer}.gs-menu-item.gs-enabled:hover{background-color:#eee}.gs-menu-item.gs-disabled{opacity:.5;cursor:not-allowed}.gs-menu-item .gs-menu-name{font-size:13px;letter-spacing:1px;flex:1}.gs-submenu-parent{position:relative;align-items:center}.gs-submenu-parent .gs-submenu-arrow{margin-left:8px;font-size:11px;opacity:.6}.gs-submenu-flyout{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;opacity:.9;transition:opacity .15s ease;min-width:200px;margin:0;color:#555;opacity:1;list-style-type:none}.gs-submenu-flyout:hover{opacity:1}.gs-menu-shortcut{font-size:10px;line-height:20px;color:#999}.gs-menu-shortcut:before{content:"( "}.gs-menu-shortcut:after{content:" )"}.gs-menu-shortcut .gs-menu-underline{text-decoration:underline}.gs-column-menu{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;opacity:.9;transition:opacity .15s ease}.gs-column-menu:hover{opacity:1}.gs-column-menu ul{color:#555;margin:0;padding:0;min-width:200px}.gs-column-menu .gs-column-menu-sort{align-items:center}.gs-column-menu .gs-column-menu-sort .gs-sort-buttons{display:flex;gap:4px;margin-left:auto}.gs-column-menu .gs-column-menu-sort .gs-sort-btn{font-size:12px;padding:4px 8px;border:1px solid transparent;border-radius:3px;background-color:rgba(180,180,180,.1);cursor:pointer;color:#555;font-weight:700;letter-spacing:.5px}.gs-column-menu .gs-column-menu-sort .gs-sort-btn:hover:not(:disabled){border-color:#555}.gs-column-menu .gs-column-menu-sort .gs-sort-btn:disabled{opacity:.5;cursor:not-allowed}.gs-column-menu .gs-column-menu-label{padding:5px 10px}.gs-column-menu .gs-label-input-row{display:flex;gap:4px;align-items:center}.gs-column-menu .gs-label-input{flex:1;font-size:13px;padding:4px 6px;border:none;border-bottom:1px solid #ccc;border-radius:0;outline:0;min-width:0;width:100px;background-color:transparent;box-shadow:none}.gs-column-menu .gs-label-input:focus{border-bottom-color:var(--gs-accent,#2563eb);outline:0;box-shadow:none}.gs-column-menu .gs-label-apply-btn{font-size:12px;padding:4px 8px;border:1px solid transparent;border-radius:3px;background-color:rgba(180,180,180,.1);cursor:pointer;color:#555;font-weight:700;letter-spacing:.5px}.gs-column-menu .gs-label-apply-btn:hover:not(:disabled){border-color:#555}.gs-column-menu .gs-label-apply-btn:disabled{opacity:.5;cursor:not-allowed}.gs-column-menu .gs-column-menu-filter{padding:5px 10px;list-style-type:none;font-size:13px}.gs-column-menu .gs-filter-header{display:flex;align-items:center;gap:8px}.gs-column-menu .gs-filter-header .gs-filter-add-btn{font-size:12px;padding:3px 9px;border:1px solid transparent;border-radius:3px;background-color:rgba(180,180,180,.1);cursor:pointer;color:#555;letter-spacing:1px}.gs-column-menu .gs-filter-header .gs-filter-add-btn:hover{border-color:#555}.gs-column-menu .gs-filter-mode-toggle{display:flex;gap:6px;margin-left:auto}.gs-column-menu .gs-filter-mode-toggle label{display:flex;align-items:center;gap:3px;font-size:11px;font-weight:700;letter-spacing:.5px;color:#888;cursor:pointer;user-select:none}.gs-column-menu .gs-filter-mode-toggle label input[type=radio]{margin:0;cursor:pointer}.gs-column-menu .gs-filter-mode-toggle label.gs-active{color:var(--gs-accent,#2563eb)}.gs-column-menu .gs-filter-mode-toggle.gs-disabled{opacity:.4;pointer-events:none}.gs-column-menu .gs-filter-conditions{display:flex;flex-direction:column;gap:5px;margin-top:6px;max-height:200px;overflow-y:auto}.gs-column-menu .gs-filter-condition-row{display:flex;gap:4px;align-items:normal}.gs-column-menu .gs-filter-method-select{font-size:12px;padding:4px 4px;border:none;border-bottom:1px solid #ccc;border-radius:0;outline:0;background-color:#fff;box-shadow:none;min-width:40px;max-width:80px;cursor:pointer}.gs-column-menu .gs-filter-method-select:focus{border-bottom-color:var(--gs-accent,#2563eb);outline:0;box-shadow:none}.gs-column-menu .gs-filter-value-input{flex:1;font-size:13px;padding:4px 6px;border:none;border-bottom:1px solid #ccc;border-radius:0;outline:0;min-width:0;width:80px;background-color:transparent;box-shadow:none}.gs-column-menu .gs-filter-value-input:focus{border-bottom-color:var(--gs-accent,#2563eb);outline:0;box-shadow:none}.gs-column-menu .gs-filter-remove-btn{font-size:12px;padding:0;border:none;border-radius:3px;background-color:transparent;cursor:pointer;color:#999;line-height:1;flex-shrink:0}.gs-column-menu .gs-filter-remove-btn:hover{color:#c33}.gs-column-menu .gs-filter-actions{display:flex;gap:4px;margin-top:10px;align-items:center}.gs-column-menu .gs-filter-actions .gs-filter-reset-all-btn{font-size:12px;padding:3px 9px;border:1px solid transparent;border-radius:3px;background-color:transparent;cursor:pointer;color:#c33;font-weight:700;letter-spacing:1px}.gs-column-menu .gs-filter-actions .gs-filter-reset-all-btn:hover{border-color:#c33}.gs-column-menu .gs-filter-actions .gs-filter-actions-right{display:flex;gap:4px;margin-left:auto}.gs-column-menu .gs-filter-actions .gs-filter-reset-btn{font-size:12px;padding:3px 9px;border:1px solid transparent;border-radius:3px;background-color:transparent;cursor:pointer;color:#e08000;font-weight:700;letter-spacing:1px}.gs-column-menu .gs-filter-actions .gs-filter-reset-btn:hover{border-color:#e08000}.gs-column-menu .gs-filter-actions .gs-filter-apply-btn{font-size:12px;padding:3px 6px;border:1px solid transparent;border-radius:3px;background-color:transparent;color:var(--gs-accent,#2563eb);cursor:pointer;font-weight:700;letter-spacing:1px}.gs-column-menu .gs-filter-actions .gs-filter-apply-btn:hover{border-color:var(--gs-accent,#2563eb)}.gs-column-menu-waiting{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:20px 30px;gap:12px;min-width:180px}.gs-column-menu-waiting .gs-waiting-message{font-size:13px;font-weight:700;color:#555;letter-spacing:.5px}.gs-column-menu-waiting .gs-waiting-spinner{width:24px;height:24px;border:3px solid #e0e0e0;border-top-color:var(--gs-accent,#2563eb);border-radius:50%;animation:spin .8s linear infinite}.gs-column-menu-waiting .gs-waiting-cancel-btn{font-size:12px;padding:4px 18px;border:1px solid #c33;border-radius:3px;background-color:transparent;color:#c33;cursor:pointer;font-weight:700;letter-spacing:1px}.gs-column-menu-waiting .gs-waiting-cancel-btn:hover{background-color:#c33;color:#fff}.gs-column-menu-btn{right:4px;top:50%;transform:translateY(-50%)}.gs-column-menu-btn.gs-filtered{opacity:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);border-color:var(--gs-accent,#2563eb);color:var(--gs-accent,#2563eb)}.gs-column-menu-btn.gs-active{opacity:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 18%,transparent);border-color:var(--gs-accent,#2563eb);color:var(--gs-accent,#2563eb)}.gs-th-top:hover .gs-column-menu-btn{opacity:1}.gs-row-menu{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;opacity:.9;transition:opacity .15s ease}.gs-row-menu:hover{opacity:1}.gs-row-menu ul{color:#555;margin:0;padding:0;min-width:200px}.gs-row-fixed-toggle{display:flex;align-items:center;gap:6px}.gs-row-fixed-check{font-size:12px;width:14px;text-align:center;color:transparent}.gs-row-fixed-check.gs-row-fixed-active{color:var(--gs-accent,#2563eb)}.gs-row-menu-btn{top:50%;transform:translateY(-50%);right:2px}.gs-row-menu-btn.gs-active{opacity:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 18%,transparent);border-color:var(--gs-accent,#2563eb);color:var(--gs-accent,#2563eb)}.gs-th-left:hover .gs-row-menu-btn{opacity:1}.gs-corner-menu-btn{bottom:2px;right:2px}.gs-corner-menu-btn:hover{opacity:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 18%,transparent);border-color:var(--gs-accent,#2563eb);color:var(--gs-accent,#2563eb)}.gs-th-left.gs-th-top:hover .gs-corner-menu-btn{opacity:1}.gs-editor-hl{padding:0 2px!important;position:absolute;font-family:monospace,Arial;font-size:12px;line-height:24px;letter-spacing:1px}.gs-formula-bar-editor-inner{position:relative;flex:1;min-width:0;display:flex;align-items:center}.gs-editor{opacity:0;z-index:-1}.gs-editor .gs-editor-inner{position:relative}.gs-editor .gs-editor-hl{box-sizing:content-box;border:solid 2px var(--gs-accent,#2563eb);margin:-2px -1px}.gs-editor textarea{width:100%;padding:0 2px!important;position:absolute;font-size:12px;font-family:monospace,Arial;line-height:24px;letter-spacing:1px;top:0;left:0;border:none;outline:0;background-color:transparent;color:transparent;resize:none;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;overflow:hidden;cursor:default;white-space:pre;height:auto}.gs-editor.gs-editing{z-index:11;opacity:1}.gs-editor.gs-editing .gs-cell-label{pointer-events:none;font-family:inherit;font-weight:500;position:absolute;top:0;right:0;margin-top:-17px;margin-right:-2px;padding:1px 5px;border-top-left-radius:4px;border-top-right-radius:4px;font-size:10px;background-color:var(--gs-accent,#2563eb);color:#fff;z-index:1}.gs-formula-bar{width:100%;position:relative;display:flex;align-items:stretch;box-sizing:border-box;border-style:solid;border-color:var(--gs-border,#e3e6ea);border-width:var(--gs-fb-bt,1px) var(--gs-fb-br,1px) var(--gs-fb-bb,1px) var(--gs-fb-bl,1px);padding:3px 6px;gap:6px}.gs-formula-bar .gs-selecting-address{display:flex;align-items:center;justify-content:center;min-width:38px;padding:0 4px;color:var(--gs-muted-fg,#6b7280);font-size:12px;font-variant-numeric:tabular-nums;text-align:center}.gs-formula-bar[data-spill=true]{background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 6%,var(--gs-header-bg,#f4f5f7))}.gs-formula-bar[data-spill=true] .gs-selecting-address{color:var(--gs-accent,#2563eb);font-style:italic}.gs-formula-bar[data-spill=true] .gs-selecting-address::after{content:"\\2196";margin-left:2px;font-style:normal;font-size:9px}.gs-formula-bar .gs-fx{display:flex;align-items:center;justify-content:center;align-self:center;width:26px;height:18px;flex-shrink:0;color:var(--gs-muted-fg,#6b7280);font-style:italic;font-family:inherit;font-weight:400;text-align:center;font-size:13px;letter-spacing:.3px;border-radius:4px;background-color:color-mix(in srgb,var(--gs-fg,#1f2328) 6%,transparent)}.gs-formula-bar .gs-editor-hl{z-index:0;overflow-y:auto;box-sizing:border-box;white-space:pre-wrap;word-break:break-all;text-align:left;line-height:24px}.gs-formula-bar textarea{position:relative;z-index:1;width:100%;vertical-align:bottom;color:transparent;border:none;background-color:transparent;padding:0 2px;box-sizing:border-box;text-align:left;outline:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;font-size:12px;font-family:monospace,Arial;height:24px;line-height:24px;min-height:24px;letter-spacing:1px;resize:vertical;caret-color:var(--gs-fg,#1f2328);white-space:pre-wrap;word-break:break-all}.gs-token-type-INVALID_REF{color:red}.gs-token-type-VALUE.gs-token-entity-type-boolean,.gs-token-type-VALUE.gs-token-entity-type-number{color:#39f}.gs-token-type-VALUE.gs-token-entity-type-string{color:#090}.gs-editor-options{position:fixed;z-index:1000;padding:4px;background:var(--gs-bg,#fff);box-shadow:0 4px 12px rgba(0,0,0,.15);border:1px solid rgba(0,0,0,.1);border-radius:6px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;overflow:visible}.gs-editor-option{position:relative;cursor:pointer;list-style:none;padding:6px 12px;font-size:13px;border-radius:4px;color:#333;margin-bottom:2px}.gs-editor-option-content{display:flex;justify-content:space-between;width:100%;align-items:center}.gs-editor-option-tab{font-size:10px;color:#aaa;margin-left:8px;padding:2px 4px;border:1px solid #ddd;border-radius:3px;background:#f9f9f9}.gs-editor-option:last-child{margin-bottom:0}.gs-editor-option:hover{background-color:#f5f5f5}.gs-editor-option-selected{background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);color:var(--gs-accent,#2563eb);font-weight:500}.gs-editor-option-selected:hover{background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 18%,transparent)}.gs-fn-guide1{position:absolute;top:-4px;left:calc(100% + 8px);background:#fff;border:1px solid rgba(0,0,0,.1);box-shadow:0 4px 16px rgba(0,0,0,.12);border-radius:6px;padding:16px;width:280px;z-index:1000;cursor:default;white-space:normal;color:#333}.gs-fn-guide1-tooltip{margin-bottom:8px;line-height:1.4;font-size:13px}.gs-fn-guide1-example{font-family:monospace;font-weight:600;font-size:13px;margin-bottom:8px;color:#1a1a1a;background:#f5f5f5;padding:6px 8px;border-radius:4px;border:1px solid #eee;display:flex;align-items:center;gap:6px;flex-wrap:wrap}.gs-fn-guide1-desc{font-size:13px;color:#555;margin-bottom:12px;line-height:1.4}.gs-fn-guide1-desc p{margin:0 0 6px 0}.gs-fn-guide1-desc p:last-child{margin-bottom:0}.gs-fn-guide1-args{border-top:1px solid #eee;padding-top:10px}.gs-fn-guide1-arg{margin-bottom:6px;line-height:1.4;font-size:12px}.gs-fn-guide1-arg-name{font-weight:600;color:var(--gs-accent,#2563eb)}.gs-fn-guide1-arg-opt{color:#888;font-size:11px}.gs-fn-guide1-arg-iter{font-weight:600;color:var(--gs-accent,#2563eb)}.gs-fn-guide1-arg-type{color:var(--gs-accent,#2563eb);padding:0 4px;background:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);border-radius:3px;font-size:11px;margin:0 4px}.gs-fn-guide1-arg-desc{color:#666}.gs-fn-guide-category{position:absolute;top:-11px;right:8px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;font-size:11px;font-weight:600;letter-spacing:.5px;text-transform:uppercase;padding:2px 7px;border-radius:4px;background:#e8eaf6;color:#3949ab;border:1px solid #c5cae9;white-space:nowrap}.gs-fn-guide-category.gs-fn-guide-category-math{background:#e3f2fd;color:#1565c0;border-color:#bbdefb}.gs-fn-guide-category.gs-fn-guide-category-statistics{background:#e8f5e9;color:#2e7d32;border-color:#c8e6c9}.gs-fn-guide-category.gs-fn-guide-category-text{background:#fff8e1;color:#f57f17;border-color:#ffecb3}.gs-fn-guide-category.gs-fn-guide-category-time{background:#fce4ec;color:#880e4f;border-color:#f8bbd0}.gs-fn-guide-category.gs-fn-guide-category-lookup{background:#f3e5f5;color:#6a1b9a;border-color:#e1bee7}.gs-fn-guide-category.gs-fn-guide-category-logical{background:#e0f2f1;color:#00695c;border-color:#b2dfdb}.gs-fn-guide-category.gs-fn-guide-category-information{background:#e0f7fa;color:#006064;border-color:#b2ebf2}.gs-fn-guide-category.gs-fn-guide-category-finance{background:#fff3e0;color:#e65100;border-color:#ffe0b2}.gs-fn-guide-category.gs-fn-guide-category-engineering{background:#efebe9;color:#4e342e;border-color:#d7ccc8}.gs-fn-guide-category.gs-fn-guide-category-ai{background:#e8eaf6;color:#3949ab;border-color:#c5cae9}.gs-fn-guide-category.gs-fn-guide-category-other{background:#f5f5f5;color:#616161;border-color:#e0e0e0}.gs-editor-portal{display:contents}.gs-editor-portal[data-mode=dark] .gs-editor-options,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-options,.gs-editor[data-mode=dark] .gs-editor-options,.gs-editor[data-mode=inherit-dark] .gs-editor-options{background:#252526;border-color:#454545;box-shadow:0 4px 12px rgba(0,0,0,.5)}.gs-editor-portal[data-mode=dark] .gs-editor-option,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option,.gs-editor[data-mode=dark] .gs-editor-option,.gs-editor[data-mode=inherit-dark] .gs-editor-option{color:#ccc}.gs-editor-portal[data-mode=dark] .gs-editor-option:hover,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option:hover,.gs-editor[data-mode=dark] .gs-editor-option:hover,.gs-editor[data-mode=inherit-dark] .gs-editor-option:hover{background-color:#333}.gs-editor-portal[data-mode=dark] .gs-editor-option-selected,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option-selected,.gs-editor[data-mode=dark] .gs-editor-option-selected,.gs-editor[data-mode=inherit-dark] .gs-editor-option-selected{background-color:#094771;color:#fff}.gs-editor-portal[data-mode=dark] .gs-editor-option-selected:hover,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option-selected:hover,.gs-editor[data-mode=dark] .gs-editor-option-selected:hover,.gs-editor[data-mode=inherit-dark] .gs-editor-option-selected:hover{background-color:#0d5a8f}.gs-editor-portal[data-mode=dark] .gs-editor-option-tab,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option-tab,.gs-editor[data-mode=dark] .gs-editor-option-tab,.gs-editor[data-mode=inherit-dark] .gs-editor-option-tab{color:#777;background:#333;border-color:#444}.gs-editor-portal[data-mode=dark] .gs-fn-guide1,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1,.gs-editor[data-mode=dark] .gs-fn-guide1,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1{background:#252526;border-color:#454545;color:#ccc}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-example,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-example,.gs-editor[data-mode=dark] .gs-fn-guide1-example,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-example{background:#1e1e1e;border-color:#333;color:#d4d4d4}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-desc,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-desc,.gs-editor[data-mode=dark] .gs-fn-guide1-desc,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-desc{color:#aaa}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-args,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-args,.gs-editor[data-mode=dark] .gs-fn-guide1-args,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-args{border-color:#333}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-iter,.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-name,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-iter,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-name,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-iter,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-name,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-iter,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-name{color:#4fc1ff}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-opt,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-opt,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-opt,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-opt{color:#777}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-type,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-type,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-type,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-type{background:#094771;color:#4fc1ff}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-desc,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-desc,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-desc,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-desc{color:#999}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category,.gs-editor[data-mode=dark] .gs-fn-guide-category,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category{background:#2a2d3e;color:#7986cb;border-color:#3d4166}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-math,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-math,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-math,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-math{background:#0d2137;color:#64b5f6;border-color:#1a3a5c}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-statistics,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-statistics,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-statistics,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-statistics{background:#0d2218;color:#66bb6a;border-color:#1a3d2a}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-text,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-text,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-text,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-text{background:#2e2200;color:#ffd54f;border-color:#4d3900}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-time,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-time,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-time,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-time{background:#2d0d1e;color:#f48fb1;border-color:#4d1a33}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-lookup,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-lookup,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-lookup,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-lookup{background:#260d33;color:#ce93d8;border-color:#3d1a54}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-logical,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-logical,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-logical,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-logical{background:#0d2421;color:#4db6ac;border-color:#1a3d39}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-information,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-information,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-information,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-information{background:#0d2426;color:#4dd0e1;border-color:#1a3d40}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-finance,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-finance,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-finance,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-finance{background:#2e1500;color:#ffb74d;border-color:#4d2800}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-engineering,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-engineering,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-engineering,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-engineering{background:#1e1714;color:#bcaaa4;border-color:#332c28}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-ai,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-ai,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-ai,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-ai{background:#10142e;color:#7986cb;border-color:#232a52}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-other,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-other,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-other,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-other{background:#1e1e1e;color:#9e9e9e;border-color:#333}.gs-editor-portal[data-mode=dark] .gs-fn-guide2,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2,.gs-editor[data-mode=dark] .gs-fn-guide2,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2{background:#252526;border-color:#454545;box-shadow:0 4px 12px rgba(0,0,0,.5);color:#ccc}.gs-editor-portal[data-mode=dark] .gs-fn-guide2-name,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2-name,.gs-editor[data-mode=dark] .gs-fn-guide2-name,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2-name{color:#dfdbdb;background:#333;border-color:#444}.gs-editor-portal[data-mode=dark] .gs-fn-guide2 .gs-active-arg,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2 .gs-active-arg,.gs-editor[data-mode=dark] .gs-fn-guide2 .gs-active-arg,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2 .gs-active-arg{color:#fff;background-color:#094771}.gs-editor-portal[data-mode=dark] .gs-fn-guide2-arg-type,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2-arg-type,.gs-editor[data-mode=dark] .gs-fn-guide2-arg-type,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2-arg-type{background:#094771;color:#4fc1ff}.gs-editor-portal[data-mode=dark] .gs-fn-guide2-desc,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2-desc,.gs-editor[data-mode=dark] .gs-fn-guide2-desc,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2-desc{color:#aaa;border-top-color:#333}.gs-fn-guide2{position:fixed;left:0;background:#fff;border:1px solid rgba(0,0,0,.1);box-shadow:0 4px 16px rgba(0,0,0,.12);border-radius:6px;padding:12px 16px;width:280px;z-index:1000;cursor:default;white-space:normal;color:#333;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;transition:opacity .1s ease-in-out}.gs-fn-guide2.gs-fn-guide2-hidden{opacity:0!important;pointer-events:none!important}.gs-fn-guide2-name{font-family:monospace;font-weight:700;font-size:13px;color:#1a1a1a;background:#f5f5f5;padding:6px 8px;border-radius:4px;border:1px solid #eee;display:flex;align-items:center;gap:6px;flex-wrap:wrap;width:100%;box-sizing:border-box;margin-bottom:8px}.gs-fn-guide2-args-inline{font-size:13px;font-family:monospace;line-height:1.5;margin-bottom:8px;color:#666}.gs-fn-guide2-args-inline span{transition:all .2s ease-in-out}.gs-fn-guide2 .gs-active-arg{font-weight:700;color:var(--gs-accent,#2563eb);background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);padding:2px 4px;margin:0 -4px;border-radius:4px}.gs-fn-guide2-arg-type{color:var(--gs-accent,#2563eb);padding:0 4px;background:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);border-radius:3px;font-size:11px;margin:0 4px}.gs-fn-guide2-desc{font-size:12px;color:#555;line-height:1.4;border-top:1px solid #eee;padding-top:8px;margin-top:4px}.gs-fn-guide2-desc p{margin:0}.gs-fn-guide2-desc-more{font-style:italic;color:#888;margin-top:4px!important;font-size:11px}.gs-adjuster{padding:0}.gs-table{margin:0}.gs-tabular{overflow:auto;overflow-anchor:none;display:flex;box-sizing:border-box;position:relative}.gs-root1[data-matrix-align=both] .gs-tabular,.gs-root1[data-matrix-align=horizontal] .gs-tabular{justify-content:safe center}.gs-root1[data-matrix-align=both] .gs-tabular,.gs-root1[data-matrix-align=vertical] .gs-tabular{align-items:safe center}.gs-tabular-inner{flex:0 0 auto;position:relative;overflow:hidden;overflow:clip;box-sizing:border-box;border-right:solid var(--gs-mx-br,1px) var(--gs-border,#e3e6ea);border-bottom:solid var(--gs-mx-bb,1px) var(--gs-border,#e3e6ea)}.gs-tabular-inner>table{table-layout:fixed;border-collapse:collapse;border-spacing:0}.gs-main[data-overflow-x=true] .gs-tabular-inner{border-right-width:0}.gs-main[data-overflow-y=true] .gs-tabular-inner{border-bottom-width:0}.gs-main::after{content:'';position:absolute;inset:0;pointer-events:none;z-index:3;border:0 solid var(--gs-border,#e3e6ea)}.gs-main[data-overflow-x=true]::after{border-right-width:var(--gs-mx-br,1px)}.gs-main[data-overflow-y=true]::after{border-bottom-width:var(--gs-mx-bb,1px)}.gs-th{z-index:2;padding:0;position:sticky;font-size:13px;font-weight:400;box-sizing:border-box;vertical-align:top}.gs-th .gs-resizer{position:absolute;border-color:transparent;box-sizing:border-box;z-index:2}.gs-th .gs-resizer:hover{background-color:var(--gs-accent,#2563eb)}.gs-th .gs-resizer.gs-protected{display:none}.gs-th-inner{height:100%;box-sizing:border-box;vertical-align:middle;overflow:hidden;display:flex;align-items:center;justify-content:center}.gs-th-inner-wrap{height:100%;box-sizing:border-box;background-color:transparent}.gs-th-top{top:0;overflow:hidden}.gs-th-top .gs-resizer{top:0;right:0;width:3px;cursor:e-resize}.gs-th-top .gs-resizer.gs-dragging{border-right-style:dotted;height:1000000px!important;cursor:e-resize}.gs-th-left{left:0;overflow:hidden;min-width:30px;border-top:solid 1px var(--gs-border,#e3e6ea)}.gs-th-left .gs-resizer{left:0;bottom:0;height:3px;cursor:n-resize}.gs-th-left .gs-resizer.gs-dragging{border-bottom-style:dotted;width:1000000px!important;cursor:n-resize}.gs-th-top.gs-th-left{top:0;left:0;z-index:3;border:none!important}.gs-th-left.gs-filter-fixed .gs-th-inner::before{content:'‹\\00a0'}.gs-th-left.gs-sort-fixed .gs-th-inner::after{content:'\\00a0›'}.gs-col-addr{position:absolute;top:2px;right:4px;font-size:9px;opacity:.5;line-height:1;letter-spacing:.3px;pointer-events:none}.gs-search-bar{width:100%;display:flex;align-items:center;padding:3px 0;border-top:solid 1px rgba(128,128,128,.3);border-left:solid 1px rgba(128,128,128,.3);border-right:solid 1px rgba(128,128,128,.3);border-bottom:solid 1px rgba(128,128,128,.3);box-sizing:border-box;background-color:rgba(200,50,0,.2)}.gs-search-bar.gs-search-found{background-color:rgba(0,200,100,.2)}.gs-search-bar .gs-search-bar-inner{border-left:solid 1px rgba(128,128,128,.5)}.gs-search-bar .gs-search-bar-icon{border-left:solid 1px rgba(128,128,128,.3);display:flex;align-items:center;justify-content:center;width:30px;flex-shrink:0}.gs-search-bar .gs-search-input-wrapper{flex-grow:1;position:relative;display:flex;align-items:center;height:100%}.gs-search-bar .gs-search-input-ghost{position:absolute;left:2px;right:2px;top:0;bottom:0;pointer-events:none;font-size:12px;font-family:monospace,Arial;line-height:24px;letter-spacing:1px;white-space:pre-wrap;word-break:break-all;color:transparent;overflow:hidden}.gs-search-bar .gs-search-input-ghost .gs-search-ghost-hint{color:#aaa}.gs-search-bar textarea{background-color:transparent;border:none;padding:0 2px;box-sizing:border-box;outline:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;font-size:12px;font-family:monospace,Arial;height:24px;line-height:24px;min-height:24px;letter-spacing:1px;caret-color:rgba(128,128,128);white-space:pre-wrap;word-break:break-all;flex-grow:1;width:100%;resize:none}.gs-search-progress{color:#999;font-size:13px;width:60px;flex-shrink:0;white-space:nowrap;text-align:center}.gs-search-close{cursor:pointer;display:flex;align-items:center;justify-content:center;width:24px;flex-shrink:0}.gs-search-buttons{display:flex;align-items:center;white-space:nowrap;flex-shrink:0}.gs-search-button{display:inline-flex;cursor:pointer;margin:0 2px}.gs-search-button span{display:inline-block;font-size:11px;padding:3px 5px;background-color:rgba(128,128,128,.1);border:1px solid rgba(128,128,128,.3);border-radius:3px;transition:all .15s ease;line-height:1}.gs-search-button span:hover{background-color:rgba(128,128,128,.2)}.gs-search-button span.gs-search-button-on{color:var(--gs-accent,#2563eb);background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 22%,transparent);border-color:var(--gs-accent,#2563eb)}.gs-search-range span{white-space:nowrap;font-family:monospace}@keyframes spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}.gs-loading-overlay{position:absolute;top:0;left:0;right:0;bottom:0;background:color-mix(in srgb,var(--gs-surface,#fff) 70%,transparent);display:flex;align-items:center;justify-content:center;z-index:100;pointer-events:all}.gs-loading-spinner{width:32px;height:32px;border:3px solid color-mix(in srgb,var(--gs-fg,#1f2328) 12%,transparent);border-top-color:var(--gs-accent,#2563eb);border-radius:50%;animation:spin .8s linear infinite}.gs-progress-overlay{position:absolute;top:0;left:0;right:0;bottom:0;z-index:100;pointer-events:all;display:flex;align-items:center;justify-content:center}.gs-progress-box{min-width:240px;padding:16px 18px;border-radius:8px;background:var(--gs-editor-surface,#fff);border:1px solid var(--gs-border,#e3e6ea);box-shadow:0 6px 24px rgba(0,0,0,.28);display:flex;flex-direction:column;gap:10px}.gs-progress-head{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--gs-fg,#1f2328)}.gs-progress-head .gs-loading-spinner{width:15px;height:15px;border-width:2px}.gs-progress-track{height:6px;border-radius:3px;overflow:hidden;background:color-mix(in srgb,var(--gs-fg,#1f2328) 12%,transparent)}.gs-progress-fill{height:100%;border-radius:3px;background:var(--gs-accent,#2563eb);transition:width .1s linear}@keyframes gs-pending-slide{0%{left:-40%}100%{left:100%}}@keyframes gs-pending-pulse{0%{left:0;width:0}50%{left:0;width:100%}100%{left:100%;width:0}}@keyframes gs-flash{0%{opacity:0}20%{opacity:1}100%{opacity:0}}.gs-flash-overlay{position:absolute;inset:0;pointer-events:none;z-index:9999;background:color-mix(in srgb,var(--gs-accent,#2563eb) 15%,transparent);opacity:0}.gs-flash-overlay--active{animation:gs-flash .6s ease-out forwards}`; +export const LAST_MODIFIED = 1791034553; +export const CSS = `.gs-root1{display:inline-block;position:relative;border-spacing:0;width:fit-content;max-width:100%;overflow:auto;font-family:"SF Pro Text","SF Pro Icons","Helvetica Neue",Helvetica,Arial,Meiryo,sans-serif;visibility:hidden;opacity:0}.gs-root1.gs-initialized{visibility:visible;opacity:1;transition:opacity .2s ease-in-out}.gs-root1 .gs-main{flex:1;max-width:100%;overflow:hidden;position:relative;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box}.gs-root1 .gs-resizing{width:100%;height:100%;position:absolute;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 8%,transparent);top:0;left:0;z-index:2}.gs-root1 .gs-line-horizontal{width:100%}.gs-root1 .gs-line-vertical{height:100%}.gs-root1 .gs-line{position:relative;top:0;left:0;border:dotted 1px var(--gs-accent,#2563eb);box-sizing:border-box}.gs-root1 .gs-line span{font-size:10px;padding:3px;background-color:var(--gs-accent,#2563eb);color:#fff;margin:0;position:absolute;top:0;left:0}.gs-root1 .gs-scroll-handle{width:100%;height:100%;cursor:cell}.gs-hidden{visibility:hidden;position:absolute;top:0;left:0;width:0;height:0;overflow:hidden;pointer-events:none;z-index:-1}.gs-fixed{position:fixed;top:0;left:0;z-index:1}:where(.gs-root1[data-mode=light],.gs-editor[data-mode=light]){--gs-fg:#1f2328;--gs-muted-fg:#6b7280;--gs-border:#e3e6ea;--gs-bg:rgba(128, 128, 128, 0.07);--gs-canvas:transparent;--gs-surface:#ffffff;--gs-editor-surface:#ffffff;--gs-header-bg:#f4f5f7;--gs-header-fg:#59616b;--gs-accent:#2563eb}.gs-root1{background-color:var(--gs-bg);color:var(--gs-fg)}.gs-root1 .gs-main{background-color:var(--gs-canvas)}.gs-root1 .gs-tabular{background-color:var(--gs-canvas)}.gs-root1 .gs-sheet-body-data{background-color:var(--gs-surface)}.gs-root1 .gs-formula-bar{background-color:var(--gs-header-bg)}.gs-root1 .gs-formula-bar-editor-inner{color:var(--gs-fg)}.gs-root1 .gs-cell{border:solid 1px var(--gs-border)}.gs-root1 .gs-adjuster{background-color:var(--gs-border)}.gs-root1 .gs-tabular-inner{background-color:var(--gs-border)}.gs-root1 .gs-large-editor textarea{color:var(--gs-fg);caret-color:var(--gs-fg)}.gs-root1 .gs-th{background-color:var(--gs-header-bg);color:var(--gs-header-fg)}.gs-root1 .gs-th-top{border-left:solid 1px var(--gs-border)}.gs-root1 .gs-th-top .gs-th-inner{border-top:solid var(--gs-mx-bt,1px) var(--gs-border)}.gs-root1 .gs-th-left{border-top:solid 1px var(--gs-border)}.gs-root1 .gs-th-left .gs-th-inner{border-left:solid var(--gs-mx-bl,1px) var(--gs-border)}.gs-root1 .gs-search-bar{color:color-mix(in srgb,var(--gs-fg) 40%,transparent)}.gs-root1 .gs-search-bar textarea{color:var(--gs-fg);caret-color:var(--gs-fg)}.gs-editor.gs-editing textarea{caret-color:var(--gs-fg)}.gs-editor.gs-editing .gs-editor-hl{background-color:var(--gs-editor-surface);color:var(--gs-fg)}.gs-editor .gs-editor-options{color:var(--gs-fg);background-color:var(--gs-editor-surface);border:solid 1px var(--gs-border)}:where(.gs-root1[data-mode=dark],.gs-editor[data-mode=dark]){--gs-fg:#e4e6e9;--gs-muted-fg:#8b9096;--gs-border:#2c2f34;--gs-bg:rgba(128, 128, 128, 0.07);--gs-canvas:transparent;--gs-surface:#1c1e21;--gs-editor-surface:#1c1e21;--gs-header-bg:#212327;--gs-header-fg:#a6abb2;--gs-accent:#3b82f6}:where(.gs-root1[data-mode=auto],.gs-editor[data-mode=auto]){--gs-fg:#1f2328;--gs-muted-fg:#6b7280;--gs-border:#e3e6ea;--gs-bg:rgba(128, 128, 128, 0.07);--gs-canvas:transparent;--gs-surface:#ffffff;--gs-editor-surface:#ffffff;--gs-header-bg:#f4f5f7;--gs-header-fg:#59616b;--gs-accent:#2563eb}@media (prefers-color-scheme:dark){:where(.gs-root1[data-mode=auto],.gs-editor[data-mode=auto]){--gs-fg:#e4e6e9;--gs-muted-fg:#8b9096;--gs-border:#2c2f34;--gs-bg:rgba(128, 128, 128, 0.07);--gs-canvas:transparent;--gs-surface:#1c1e21;--gs-editor-surface:#1c1e21;--gs-header-bg:#212327;--gs-header-fg:#a6abb2;--gs-accent:#3b82f6}}:where(.gs-root1[data-mode=inherit-light],.gs-editor[data-mode=inherit-light]){--gs-fg:#1f2328;--gs-muted-fg:#6b7280;--gs-border:#e3e6ea;--gs-bg:rgba(128, 128, 128, 0.07);--gs-surface:#ffffff;--gs-editor-surface:#ffffff;--gs-header-bg:#f4f5f7;--gs-header-fg:#59616b;--gs-accent:#2563eb;--gs-bg:transparent;--gs-canvas:transparent;--gs-surface:transparent;--gs-header-bg:transparent}:where(.gs-root1[data-mode=inherit-dark],.gs-editor[data-mode=inherit-dark]){--gs-fg:#e4e6e9;--gs-muted-fg:#8b9096;--gs-border:#2c2f34;--gs-bg:rgba(128, 128, 128, 0.07);--gs-surface:#1c1e21;--gs-editor-surface:#1c1e21;--gs-header-bg:#212327;--gs-header-fg:#a6abb2;--gs-accent:#3b82f6;--gs-bg:transparent;--gs-canvas:transparent;--gs-surface:transparent;--gs-header-bg:transparent}.gs-root1[data-mode=inherit-dark] .gs-adjuster,.gs-root1[data-mode=inherit-dark] .gs-tabular-inner,.gs-root1[data-mode=inherit-light] .gs-adjuster,.gs-root1[data-mode=inherit-light] .gs-tabular-inner{background-color:transparent}.gs-root1[data-mode=inherit-light] .gs-th{background-color:rgba(128,128,128,.1);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}.gs-root1[data-mode=inherit-dark] .gs-th{background-color:rgba(128,128,128,.1);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}.gs-root1[data-gridlines=horizontal] .gs-cell{border-left-color:transparent;border-right-color:transparent}.gs-root1[data-gridlines=none] .gs-cell{border-color:transparent}.gs-root1[data-density=comfortable] .gs-cell-rendered{padding:0 10px}.gs-cell{transition:border-color .2s ease;padding:0;margin:0;box-sizing:border-box;position:relative;font-size:13px;letter-spacing:1px;line-height:24px;cursor:cell;user-select:none;-webkit-user-select:none;-moz-user-select:none}.gs-cell.gs-copying textarea:focus{outline:solid 1px var(--gs-accent,#2563eb)}.gs-cell.gs-selecting{z-index:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 7%,transparent)}.gs-cell.gs-selecting .gs-cell-label{display:block}.gs-cell.gs-choosing{margin-top:-1px;margin-left:-1px;z-index:1}.gs-cell.gs-choosing.gs-editing{color:transparent}.gs-cell.gs-choosing .gs-cell-label{display:block}.gs-cell.gs-pending .gs-cell-rendered{position:relative;overflow:hidden}.gs-cell.gs-pending .gs-cell-rendered::after{content:'';position:absolute;bottom:0;left:0;height:4px;width:40%;border-radius:1px;background:color-mix(in srgb,var(--gs-accent,#2563eb) 65%,transparent);animation:gs-pending-slide 1.4s ease-in-out infinite}.gs-cell .gs-formula-error-triangle{position:absolute;top:0;right:0;border-top:4px solid rgba(200,0,0,.9);border-right:4px solid rgba(200,0,0,.9);border-bottom:4px solid transparent;border-left:4px solid transparent;z-index:2;cursor:help}.gs-cell .gs-cell-label{font-size:10px;font-weight:500;font-style:normal;font-family:inherit;letter-spacing:.2px;line-height:1.4;position:absolute;top:0;right:0;background-color:var(--gs-accent,#2563eb);color:#fff;padding:1px 5px;border-bottom-left-radius:4px;display:none;opacity:.92}.gs-cell .gs-cell-inner-wrap{width:100%;height:100%;position:absolute;top:0;left:0}.gs-cell .gs-cell-inner{width:100%;height:100%;overflow:hidden;display:flex;box-sizing:border-box;border:none!important}.gs-cell .gs-cell-rendered{overflow:hidden;white-space:pre-wrap;cursor:cell;word-wrap:break-word;word-break:break-all;padding:0 6px;width:100%;height:100%}.gs-cell .gs-cell-rendered>*{position:relative}.gs-cell .gs-cell-rendered>.backface{z-index:0}.gs-cell .gs-autofill-drag{background-color:var(--gs-accent,#2563eb);position:absolute;width:7px;height:7px;bottom:0;right:0;cursor:crosshair;z-index:1}.gs-cell.gs-merged-host{z-index:1}.gs-cell.gs-merged-host.gs-selecting{background-color:transparent}.gs-cell.gs-merged-host.gs-selecting .gs-cell-inner-wrap{background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 7%,transparent)}.gs-cell.gs-merged-covered{z-index:0}.gs-th[data-x="1"] .gs-th-inner-wrap{border-left:none}.gs-th[data-y="1"] .gs-th-inner-wrap{border-top:none}.gs-formula-error-tooltip{position:fixed;background-color:rgba(35,8,8,.94);color:#fff;padding:6px 10px;border-radius:4px;border-left:3px solid rgba(220,50,50,.8);font-size:12px;line-height:1.5;max-width:260px;white-space:pre-wrap;word-break:break-word;box-shadow:0 3px 10px rgba(0,0,0,.4);z-index:100;pointer-events:none;letter-spacing:.3px}.gs-menu-modal{width:100%;height:100vh;z-index:12}.gs-label-input-label{font-size:13px;letter-spacing:1px}.gs-menu-divider{background-color:#aaa;padding:0;margin:5px 0;height:1px;list-style-type:none}.gs-menu-btn{position:absolute;background-color:rgba(128,128,128,.3);border:1px solid #ccc;border-radius:50%;cursor:pointer;font-size:12px;font-weight:700;line-height:1;color:#888;width:18px;height:18px;padding:0;display:flex;align-items:center;justify-content:center;opacity:0;transition:opacity .15s ease;z-index:2}.gs-context-menu{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;opacity:.9;transition:opacity .15s ease}.gs-context-menu:hover{opacity:1}.gs-context-menu .gs-menu-items{color:#555;margin:0;padding:0;min-width:250px}.gs-menu-item{padding:5px 10px;list-style-type:none;display:flex}.gs-menu-item.gs-enabled{cursor:pointer}.gs-menu-item.gs-enabled:hover{background-color:#eee}.gs-menu-item.gs-disabled{opacity:.5;cursor:not-allowed}.gs-menu-item .gs-menu-name{font-size:13px;letter-spacing:1px;flex:1}.gs-submenu-parent{position:relative;align-items:center}.gs-submenu-parent .gs-submenu-arrow{margin-left:8px;font-size:11px;opacity:.6}.gs-submenu-flyout{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;opacity:.9;transition:opacity .15s ease;min-width:200px;margin:0;color:#555;opacity:1;list-style-type:none}.gs-submenu-flyout:hover{opacity:1}.gs-menu-shortcut{font-size:10px;line-height:20px;color:#999}.gs-menu-shortcut:before{content:"( "}.gs-menu-shortcut:after{content:" )"}.gs-menu-shortcut .gs-menu-underline{text-decoration:underline}.gs-column-menu{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;opacity:.9;transition:opacity .15s ease}.gs-column-menu:hover{opacity:1}.gs-column-menu ul{color:#555;margin:0;padding:0;min-width:200px}.gs-column-menu .gs-column-menu-sort{align-items:center}.gs-column-menu .gs-column-menu-sort .gs-sort-buttons{display:flex;gap:4px;margin-left:auto}.gs-column-menu .gs-column-menu-sort .gs-sort-btn{font-size:12px;padding:4px 8px;border:1px solid transparent;border-radius:3px;background-color:rgba(180,180,180,.1);cursor:pointer;color:#555;font-weight:700;letter-spacing:.5px}.gs-column-menu .gs-column-menu-sort .gs-sort-btn:hover:not(:disabled){border-color:#555}.gs-column-menu .gs-column-menu-sort .gs-sort-btn:disabled{opacity:.5;cursor:not-allowed}.gs-column-menu .gs-column-menu-label{padding:5px 10px}.gs-column-menu .gs-label-input-row{display:flex;gap:4px;align-items:center}.gs-column-menu .gs-label-input{flex:1;font-size:13px;padding:4px 6px;border:none;border-bottom:1px solid #ccc;border-radius:0;outline:0;min-width:0;width:100px;background-color:transparent;box-shadow:none}.gs-column-menu .gs-label-input:focus{border-bottom-color:var(--gs-accent,#2563eb);outline:0;box-shadow:none}.gs-column-menu .gs-label-apply-btn{font-size:12px;padding:4px 8px;border:1px solid transparent;border-radius:3px;background-color:rgba(180,180,180,.1);cursor:pointer;color:#555;font-weight:700;letter-spacing:.5px}.gs-column-menu .gs-label-apply-btn:hover:not(:disabled){border-color:#555}.gs-column-menu .gs-label-apply-btn:disabled{opacity:.5;cursor:not-allowed}.gs-column-menu .gs-column-menu-filter{padding:5px 10px;list-style-type:none;font-size:13px}.gs-column-menu .gs-filter-header{display:flex;align-items:center;gap:8px}.gs-column-menu .gs-filter-header .gs-filter-add-btn{font-size:12px;padding:3px 9px;border:1px solid transparent;border-radius:3px;background-color:rgba(180,180,180,.1);cursor:pointer;color:#555;letter-spacing:1px}.gs-column-menu .gs-filter-header .gs-filter-add-btn:hover{border-color:#555}.gs-column-menu .gs-filter-mode-toggle{display:flex;gap:6px;margin-left:auto}.gs-column-menu .gs-filter-mode-toggle label{display:flex;align-items:center;gap:3px;font-size:11px;font-weight:700;letter-spacing:.5px;color:#888;cursor:pointer;user-select:none}.gs-column-menu .gs-filter-mode-toggle label input[type=radio]{margin:0;cursor:pointer}.gs-column-menu .gs-filter-mode-toggle label.gs-active{color:var(--gs-accent,#2563eb)}.gs-column-menu .gs-filter-mode-toggle.gs-disabled{opacity:.4;pointer-events:none}.gs-column-menu .gs-filter-conditions{display:flex;flex-direction:column;gap:5px;margin-top:6px;max-height:200px;overflow-y:auto}.gs-column-menu .gs-filter-condition-row{display:flex;gap:4px;align-items:normal}.gs-column-menu .gs-filter-method-select{font-size:12px;padding:4px 4px;border:none;border-bottom:1px solid #ccc;border-radius:0;outline:0;background-color:#fff;box-shadow:none;min-width:40px;max-width:80px;cursor:pointer}.gs-column-menu .gs-filter-method-select:focus{border-bottom-color:var(--gs-accent,#2563eb);outline:0;box-shadow:none}.gs-column-menu .gs-filter-value-input{flex:1;font-size:13px;padding:4px 6px;border:none;border-bottom:1px solid #ccc;border-radius:0;outline:0;min-width:0;width:80px;background-color:transparent;box-shadow:none}.gs-column-menu .gs-filter-value-input:focus{border-bottom-color:var(--gs-accent,#2563eb);outline:0;box-shadow:none}.gs-column-menu .gs-filter-remove-btn{font-size:12px;padding:0;border:none;border-radius:3px;background-color:transparent;cursor:pointer;color:#999;line-height:1;flex-shrink:0}.gs-column-menu .gs-filter-remove-btn:hover{color:#c33}.gs-column-menu .gs-filter-actions{display:flex;gap:4px;margin-top:10px;align-items:center}.gs-column-menu .gs-filter-actions .gs-filter-reset-all-btn{font-size:12px;padding:3px 9px;border:1px solid transparent;border-radius:3px;background-color:transparent;cursor:pointer;color:#c33;font-weight:700;letter-spacing:1px}.gs-column-menu .gs-filter-actions .gs-filter-reset-all-btn:hover{border-color:#c33}.gs-column-menu .gs-filter-actions .gs-filter-actions-right{display:flex;gap:4px;margin-left:auto}.gs-column-menu .gs-filter-actions .gs-filter-reset-btn{font-size:12px;padding:3px 9px;border:1px solid transparent;border-radius:3px;background-color:transparent;cursor:pointer;color:#e08000;font-weight:700;letter-spacing:1px}.gs-column-menu .gs-filter-actions .gs-filter-reset-btn:hover{border-color:#e08000}.gs-column-menu .gs-filter-actions .gs-filter-apply-btn{font-size:12px;padding:3px 6px;border:1px solid transparent;border-radius:3px;background-color:transparent;color:var(--gs-accent,#2563eb);cursor:pointer;font-weight:700;letter-spacing:1px}.gs-column-menu .gs-filter-actions .gs-filter-apply-btn:hover{border-color:var(--gs-accent,#2563eb)}.gs-column-menu-waiting{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:20px 30px;gap:12px;min-width:180px}.gs-column-menu-waiting .gs-waiting-message{font-size:13px;font-weight:700;color:#555;letter-spacing:.5px}.gs-column-menu-waiting .gs-waiting-spinner{width:24px;height:24px;border:3px solid #e0e0e0;border-top-color:var(--gs-accent,#2563eb);border-radius:50%;animation:spin .8s linear infinite}.gs-column-menu-waiting .gs-waiting-cancel-btn{font-size:12px;padding:4px 18px;border:1px solid #c33;border-radius:3px;background-color:transparent;color:#c33;cursor:pointer;font-weight:700;letter-spacing:1px}.gs-column-menu-waiting .gs-waiting-cancel-btn:hover{background-color:#c33;color:#fff}.gs-column-menu-btn{right:4px;top:50%;transform:translateY(-50%)}.gs-column-menu-btn.gs-filtered{opacity:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);border-color:var(--gs-accent,#2563eb);color:var(--gs-accent,#2563eb)}.gs-column-menu-btn.gs-active{opacity:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 18%,transparent);border-color:var(--gs-accent,#2563eb);color:var(--gs-accent,#2563eb)}.gs-th-top:hover .gs-column-menu-btn{opacity:1}.gs-row-menu{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;opacity:.9;transition:opacity .15s ease}.gs-row-menu:hover{opacity:1}.gs-row-menu ul{color:#555;margin:0;padding:0;min-width:200px}.gs-row-fixed-toggle{display:flex;align-items:center;gap:6px}.gs-row-fixed-check{font-size:12px;width:14px;text-align:center;color:transparent}.gs-row-fixed-check.gs-row-fixed-active{color:var(--gs-accent,#2563eb)}.gs-row-menu-btn{top:50%;transform:translateY(-50%);right:2px}.gs-row-menu-btn.gs-active{opacity:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 18%,transparent);border-color:var(--gs-accent,#2563eb);color:var(--gs-accent,#2563eb)}.gs-th-left:hover .gs-row-menu-btn{opacity:1}.gs-corner-menu-btn{bottom:2px;right:2px}.gs-corner-menu-btn:hover{opacity:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 18%,transparent);border-color:var(--gs-accent,#2563eb);color:var(--gs-accent,#2563eb)}.gs-th-left.gs-th-top:hover .gs-corner-menu-btn{opacity:1}.gs-editor-hl{padding:0 2px!important;position:absolute;font-family:monospace,Arial;font-size:12px;line-height:24px;letter-spacing:1px}.gs-formula-bar-editor-inner{position:relative;flex:1;min-width:0;display:flex;align-items:center}.gs-editor{opacity:0;z-index:-1}.gs-editor .gs-editor-inner{position:relative}.gs-editor .gs-editor-hl{box-sizing:content-box;border:solid 2px var(--gs-accent,#2563eb);margin:-2px -1px}.gs-editor textarea{width:100%;padding:0 2px!important;position:absolute;font-size:12px;font-family:monospace,Arial;line-height:24px;letter-spacing:1px;top:0;left:0;border:none;outline:0;background-color:transparent;color:transparent;resize:none;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;overflow:hidden;cursor:default;white-space:pre;height:auto}.gs-editor.gs-editing{z-index:11;opacity:1}.gs-editor.gs-editing .gs-cell-label{pointer-events:none;font-family:inherit;font-weight:500;position:absolute;top:0;right:0;margin-top:-17px;margin-right:-2px;padding:1px 5px;border-top-left-radius:4px;border-top-right-radius:4px;font-size:10px;background-color:var(--gs-accent,#2563eb);color:#fff;z-index:1}.gs-formula-bar{width:100%;position:relative;display:flex;align-items:stretch;box-sizing:border-box;border-style:solid;border-color:var(--gs-border,#e3e6ea);border-width:var(--gs-fb-bt,1px) var(--gs-fb-br,1px) var(--gs-fb-bb,1px) var(--gs-fb-bl,1px);padding:3px 6px;gap:6px}.gs-formula-bar .gs-selecting-address{display:flex;align-items:center;justify-content:center;min-width:38px;padding:0 4px;color:var(--gs-muted-fg,#6b7280);font-size:12px;font-variant-numeric:tabular-nums;text-align:center}.gs-formula-bar[data-spill=true]{background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 6%,var(--gs-header-bg,#f4f5f7))}.gs-formula-bar[data-spill=true] .gs-selecting-address{color:var(--gs-accent,#2563eb);font-style:italic}.gs-formula-bar[data-spill=true] .gs-selecting-address::after{content:"\\2196";margin-left:2px;font-style:normal;font-size:9px}.gs-formula-bar .gs-fx{display:flex;align-items:center;justify-content:center;align-self:center;width:26px;height:18px;flex-shrink:0;color:var(--gs-muted-fg,#6b7280);font-style:italic;font-family:inherit;font-weight:400;text-align:center;font-size:13px;letter-spacing:.3px;border-radius:4px;background-color:color-mix(in srgb,var(--gs-fg,#1f2328) 6%,transparent)}.gs-formula-bar .gs-editor-hl{z-index:0;overflow-y:auto;box-sizing:border-box;white-space:pre-wrap;word-break:break-all;text-align:left;line-height:24px}.gs-formula-bar textarea{position:relative;z-index:1;width:100%;vertical-align:bottom;color:transparent;border:none;background-color:transparent;padding:0 2px;box-sizing:border-box;text-align:left;outline:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;font-size:12px;font-family:monospace,Arial;height:24px;line-height:24px;min-height:24px;letter-spacing:1px;resize:vertical;caret-color:var(--gs-fg,#1f2328);white-space:pre-wrap;word-break:break-all}.gs-token-type-INVALID_REF{color:red}.gs-token-type-VALUE.gs-token-entity-type-boolean,.gs-token-type-VALUE.gs-token-entity-type-number{color:#39f}.gs-token-type-VALUE.gs-token-entity-type-string{color:#090}.gs-editor-options{position:fixed;z-index:1000;padding:4px;background:var(--gs-bg,#fff);box-shadow:0 4px 12px rgba(0,0,0,.15);border:1px solid rgba(0,0,0,.1);border-radius:6px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;overflow:visible}.gs-editor-option{position:relative;cursor:pointer;list-style:none;padding:6px 12px;font-size:13px;border-radius:4px;color:#333;margin-bottom:2px}.gs-editor-option-content{display:flex;justify-content:space-between;width:100%;align-items:center}.gs-editor-option-tab{font-size:10px;color:#aaa;margin-left:8px;padding:2px 4px;border:1px solid #ddd;border-radius:3px;background:#f9f9f9}.gs-editor-option:last-child{margin-bottom:0}.gs-editor-option:hover{background-color:#f5f5f5}.gs-editor-option-selected{background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);color:var(--gs-accent,#2563eb);font-weight:500}.gs-editor-option-selected:hover{background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 18%,transparent)}.gs-fn-guide1{position:absolute;top:-4px;left:calc(100% + 8px);background:#fff;border:1px solid rgba(0,0,0,.1);box-shadow:0 4px 16px rgba(0,0,0,.12);border-radius:6px;padding:16px;width:280px;z-index:1000;cursor:default;white-space:normal;color:#333}.gs-fn-guide1-tooltip{margin-bottom:8px;line-height:1.4;font-size:13px}.gs-fn-guide1-example{font-family:monospace;font-weight:600;font-size:13px;margin-bottom:8px;color:#1a1a1a;background:#f5f5f5;padding:6px 8px;border-radius:4px;border:1px solid #eee;display:flex;align-items:center;gap:6px;flex-wrap:wrap}.gs-fn-guide1-desc{font-size:13px;color:#555;margin-bottom:12px;line-height:1.4}.gs-fn-guide1-desc p{margin:0 0 6px 0}.gs-fn-guide1-desc p:last-child{margin-bottom:0}.gs-fn-guide1-args{border-top:1px solid #eee;padding-top:10px}.gs-fn-guide1-arg{margin-bottom:6px;line-height:1.4;font-size:12px}.gs-fn-guide1-arg-name{font-weight:600;color:var(--gs-accent,#2563eb)}.gs-fn-guide1-arg-opt{color:#888;font-size:11px}.gs-fn-guide1-arg-iter{font-weight:600;color:var(--gs-accent,#2563eb)}.gs-fn-guide1-arg-type{color:var(--gs-accent,#2563eb);padding:0 4px;background:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);border-radius:3px;font-size:11px;margin:0 4px}.gs-fn-guide1-arg-desc{color:#666}.gs-fn-guide-category{position:absolute;top:-11px;right:8px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;font-size:11px;font-weight:600;letter-spacing:.5px;text-transform:uppercase;padding:2px 7px;border-radius:4px;background:#e8eaf6;color:#3949ab;border:1px solid #c5cae9;white-space:nowrap}.gs-fn-guide-category.gs-fn-guide-category-math{background:#e3f2fd;color:#1565c0;border-color:#bbdefb}.gs-fn-guide-category.gs-fn-guide-category-statistics{background:#e8f5e9;color:#2e7d32;border-color:#c8e6c9}.gs-fn-guide-category.gs-fn-guide-category-text{background:#fff8e1;color:#f57f17;border-color:#ffecb3}.gs-fn-guide-category.gs-fn-guide-category-time{background:#fce4ec;color:#880e4f;border-color:#f8bbd0}.gs-fn-guide-category.gs-fn-guide-category-lookup{background:#f3e5f5;color:#6a1b9a;border-color:#e1bee7}.gs-fn-guide-category.gs-fn-guide-category-logical{background:#e0f2f1;color:#00695c;border-color:#b2dfdb}.gs-fn-guide-category.gs-fn-guide-category-information{background:#e0f7fa;color:#006064;border-color:#b2ebf2}.gs-fn-guide-category.gs-fn-guide-category-finance{background:#fff3e0;color:#e65100;border-color:#ffe0b2}.gs-fn-guide-category.gs-fn-guide-category-engineering{background:#efebe9;color:#4e342e;border-color:#d7ccc8}.gs-fn-guide-category.gs-fn-guide-category-ai{background:#e8eaf6;color:#3949ab;border-color:#c5cae9}.gs-fn-guide-category.gs-fn-guide-category-other{background:#f5f5f5;color:#616161;border-color:#e0e0e0}.gs-editor-portal{display:contents}.gs-editor-portal[data-mode=dark] .gs-editor-options,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-options,.gs-editor[data-mode=dark] .gs-editor-options,.gs-editor[data-mode=inherit-dark] .gs-editor-options{background:#252526;border-color:#454545;box-shadow:0 4px 12px rgba(0,0,0,.5)}.gs-editor-portal[data-mode=dark] .gs-editor-option,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option,.gs-editor[data-mode=dark] .gs-editor-option,.gs-editor[data-mode=inherit-dark] .gs-editor-option{color:#ccc}.gs-editor-portal[data-mode=dark] .gs-editor-option:hover,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option:hover,.gs-editor[data-mode=dark] .gs-editor-option:hover,.gs-editor[data-mode=inherit-dark] .gs-editor-option:hover{background-color:#333}.gs-editor-portal[data-mode=dark] .gs-editor-option-selected,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option-selected,.gs-editor[data-mode=dark] .gs-editor-option-selected,.gs-editor[data-mode=inherit-dark] .gs-editor-option-selected{background-color:#094771;color:#fff}.gs-editor-portal[data-mode=dark] .gs-editor-option-selected:hover,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option-selected:hover,.gs-editor[data-mode=dark] .gs-editor-option-selected:hover,.gs-editor[data-mode=inherit-dark] .gs-editor-option-selected:hover{background-color:#0d5a8f}.gs-editor-portal[data-mode=dark] .gs-editor-option-tab,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option-tab,.gs-editor[data-mode=dark] .gs-editor-option-tab,.gs-editor[data-mode=inherit-dark] .gs-editor-option-tab{color:#777;background:#333;border-color:#444}.gs-editor-portal[data-mode=dark] .gs-fn-guide1,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1,.gs-editor[data-mode=dark] .gs-fn-guide1,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1{background:#252526;border-color:#454545;color:#ccc}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-example,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-example,.gs-editor[data-mode=dark] .gs-fn-guide1-example,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-example{background:#1e1e1e;border-color:#333;color:#d4d4d4}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-desc,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-desc,.gs-editor[data-mode=dark] .gs-fn-guide1-desc,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-desc{color:#aaa}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-args,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-args,.gs-editor[data-mode=dark] .gs-fn-guide1-args,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-args{border-color:#333}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-iter,.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-name,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-iter,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-name,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-iter,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-name,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-iter,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-name{color:#4fc1ff}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-opt,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-opt,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-opt,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-opt{color:#777}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-type,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-type,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-type,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-type{background:#094771;color:#4fc1ff}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-desc,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-desc,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-desc,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-desc{color:#999}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category,.gs-editor[data-mode=dark] .gs-fn-guide-category,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category{background:#2a2d3e;color:#7986cb;border-color:#3d4166}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-math,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-math,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-math,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-math{background:#0d2137;color:#64b5f6;border-color:#1a3a5c}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-statistics,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-statistics,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-statistics,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-statistics{background:#0d2218;color:#66bb6a;border-color:#1a3d2a}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-text,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-text,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-text,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-text{background:#2e2200;color:#ffd54f;border-color:#4d3900}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-time,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-time,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-time,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-time{background:#2d0d1e;color:#f48fb1;border-color:#4d1a33}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-lookup,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-lookup,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-lookup,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-lookup{background:#260d33;color:#ce93d8;border-color:#3d1a54}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-logical,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-logical,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-logical,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-logical{background:#0d2421;color:#4db6ac;border-color:#1a3d39}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-information,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-information,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-information,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-information{background:#0d2426;color:#4dd0e1;border-color:#1a3d40}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-finance,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-finance,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-finance,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-finance{background:#2e1500;color:#ffb74d;border-color:#4d2800}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-engineering,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-engineering,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-engineering,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-engineering{background:#1e1714;color:#bcaaa4;border-color:#332c28}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-ai,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-ai,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-ai,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-ai{background:#10142e;color:#7986cb;border-color:#232a52}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-other,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-other,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-other,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-other{background:#1e1e1e;color:#9e9e9e;border-color:#333}.gs-editor-portal[data-mode=dark] .gs-fn-guide2,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2,.gs-editor[data-mode=dark] .gs-fn-guide2,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2{background:#252526;border-color:#454545;box-shadow:0 4px 12px rgba(0,0,0,.5);color:#ccc}.gs-editor-portal[data-mode=dark] .gs-fn-guide2-name,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2-name,.gs-editor[data-mode=dark] .gs-fn-guide2-name,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2-name{color:#dfdbdb;background:#333;border-color:#444}.gs-editor-portal[data-mode=dark] .gs-fn-guide2 .gs-active-arg,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2 .gs-active-arg,.gs-editor[data-mode=dark] .gs-fn-guide2 .gs-active-arg,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2 .gs-active-arg{color:#fff;background-color:#094771}.gs-editor-portal[data-mode=dark] .gs-fn-guide2-arg-type,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2-arg-type,.gs-editor[data-mode=dark] .gs-fn-guide2-arg-type,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2-arg-type{background:#094771;color:#4fc1ff}.gs-editor-portal[data-mode=dark] .gs-fn-guide2-desc,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2-desc,.gs-editor[data-mode=dark] .gs-fn-guide2-desc,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2-desc{color:#aaa;border-top-color:#333}.gs-fn-guide2{position:fixed;left:0;background:#fff;border:1px solid rgba(0,0,0,.1);box-shadow:0 4px 16px rgba(0,0,0,.12);border-radius:6px;padding:12px 16px;width:280px;z-index:1000;cursor:default;white-space:normal;color:#333;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;transition:opacity .1s ease-in-out}.gs-fn-guide2.gs-fn-guide2-hidden{opacity:0!important;pointer-events:none!important}.gs-fn-guide2-name{font-family:monospace;font-weight:700;font-size:13px;color:#1a1a1a;background:#f5f5f5;padding:6px 8px;border-radius:4px;border:1px solid #eee;display:flex;align-items:center;gap:6px;flex-wrap:wrap;width:100%;box-sizing:border-box;margin-bottom:8px}.gs-fn-guide2-args-inline{font-size:13px;font-family:monospace;line-height:1.5;margin-bottom:8px;color:#666}.gs-fn-guide2-args-inline span{transition:all .2s ease-in-out}.gs-fn-guide2 .gs-active-arg{font-weight:700;color:var(--gs-accent,#2563eb);background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);padding:2px 4px;margin:0 -4px;border-radius:4px}.gs-fn-guide2-arg-type{color:var(--gs-accent,#2563eb);padding:0 4px;background:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);border-radius:3px;font-size:11px;margin:0 4px}.gs-fn-guide2-desc{font-size:12px;color:#555;line-height:1.4;border-top:1px solid #eee;padding-top:8px;margin-top:4px}.gs-fn-guide2-desc p{margin:0}.gs-fn-guide2-desc-more{font-style:italic;color:#888;margin-top:4px!important;font-size:11px}.gs-adjuster{padding:0}.gs-table{margin:0}.gs-tabular{overflow:auto;overflow-anchor:none;display:flex;box-sizing:border-box;position:relative}.gs-root1[data-matrix-align=both] .gs-tabular,.gs-root1[data-matrix-align=horizontal] .gs-tabular{justify-content:safe center}.gs-root1[data-matrix-align=both] .gs-tabular,.gs-root1[data-matrix-align=vertical] .gs-tabular{align-items:safe center}.gs-tabular-inner{flex:0 0 auto;position:relative;overflow:hidden;overflow:clip;box-sizing:border-box;border-right:solid var(--gs-mx-br,1px) var(--gs-border,#e3e6ea);border-bottom:solid var(--gs-mx-bb,1px) var(--gs-border,#e3e6ea)}.gs-tabular-inner>table{table-layout:fixed;border-collapse:collapse;border-spacing:0}.gs-ghost-cell{padding:0;box-sizing:border-box;border:dashed 1px var(--gs-border,#e3e6ea);background-color:var(--gs-surface,#fff);opacity:.5;cursor:crosshair}.gs-ghost-th{opacity:.5}.gs-ghost-th-top{top:0}.gs-ghost-th-left{left:0}.gs-main[data-overflow-x=true] .gs-tabular-inner{border-right-width:0}.gs-main[data-overflow-y=true] .gs-tabular-inner{border-bottom-width:0}.gs-main::after{content:'';position:absolute;inset:0;pointer-events:none;z-index:3;border:0 solid var(--gs-border,#e3e6ea)}.gs-main[data-overflow-x=true]::after{border-right-width:var(--gs-mx-br,1px)}.gs-main[data-overflow-y=true]::after{border-bottom-width:var(--gs-mx-bb,1px)}.gs-th{z-index:2;padding:0;position:sticky;font-size:13px;font-weight:400;box-sizing:border-box;vertical-align:top}.gs-th .gs-resizer{position:absolute;border-color:transparent;box-sizing:border-box;z-index:2}.gs-th .gs-resizer:hover{background-color:var(--gs-accent,#2563eb)}.gs-th .gs-resizer.gs-protected{display:none}.gs-th-inner{height:100%;box-sizing:border-box;vertical-align:middle;overflow:hidden;display:flex;align-items:center;justify-content:center}.gs-th-inner-wrap{height:100%;box-sizing:border-box;background-color:transparent}.gs-th-top{top:0;overflow:hidden}.gs-th-top .gs-resizer{top:0;right:0;width:3px;cursor:e-resize}.gs-th-top .gs-resizer.gs-dragging{border-right-style:dotted;height:1000000px!important;cursor:e-resize}.gs-th-left{left:0;overflow:hidden;min-width:30px;border-top:solid 1px var(--gs-border,#e3e6ea)}.gs-th-left .gs-resizer{left:0;bottom:0;height:3px;cursor:n-resize}.gs-th-left .gs-resizer.gs-dragging{border-bottom-style:dotted;width:1000000px!important;cursor:n-resize}.gs-th-top.gs-th-left{top:0;left:0;z-index:3;border:none!important}.gs-th-left.gs-filter-fixed .gs-th-inner::before{content:'‹\\00a0'}.gs-th-left.gs-sort-fixed .gs-th-inner::after{content:'\\00a0›'}.gs-col-addr{position:absolute;top:2px;right:4px;font-size:9px;opacity:.5;line-height:1;letter-spacing:.3px;pointer-events:none}.gs-search-bar{width:100%;display:flex;align-items:center;padding:3px 0;border-top:solid 1px rgba(128,128,128,.3);border-left:solid 1px rgba(128,128,128,.3);border-right:solid 1px rgba(128,128,128,.3);border-bottom:solid 1px rgba(128,128,128,.3);box-sizing:border-box;background-color:rgba(200,50,0,.2)}.gs-search-bar.gs-search-found{background-color:rgba(0,200,100,.2)}.gs-search-bar .gs-search-bar-inner{border-left:solid 1px rgba(128,128,128,.5)}.gs-search-bar .gs-search-bar-icon{border-left:solid 1px rgba(128,128,128,.3);display:flex;align-items:center;justify-content:center;width:30px;flex-shrink:0}.gs-search-bar .gs-search-input-wrapper{flex-grow:1;position:relative;display:flex;align-items:center;height:100%}.gs-search-bar .gs-search-input-ghost{position:absolute;left:2px;right:2px;top:0;bottom:0;pointer-events:none;font-size:12px;font-family:monospace,Arial;line-height:24px;letter-spacing:1px;white-space:pre-wrap;word-break:break-all;color:transparent;overflow:hidden}.gs-search-bar .gs-search-input-ghost .gs-search-ghost-hint{color:#aaa}.gs-search-bar textarea{background-color:transparent;border:none;padding:0 2px;box-sizing:border-box;outline:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;font-size:12px;font-family:monospace,Arial;height:24px;line-height:24px;min-height:24px;letter-spacing:1px;caret-color:rgba(128,128,128);white-space:pre-wrap;word-break:break-all;flex-grow:1;width:100%;resize:none}.gs-search-progress{color:#999;font-size:13px;width:60px;flex-shrink:0;white-space:nowrap;text-align:center}.gs-search-close{cursor:pointer;display:flex;align-items:center;justify-content:center;width:24px;flex-shrink:0}.gs-search-buttons{display:flex;align-items:center;white-space:nowrap;flex-shrink:0}.gs-search-button{display:inline-flex;cursor:pointer;margin:0 2px}.gs-search-button span{display:inline-block;font-size:11px;padding:3px 5px;background-color:rgba(128,128,128,.1);border:1px solid rgba(128,128,128,.3);border-radius:3px;transition:all .15s ease;line-height:1}.gs-search-button span:hover{background-color:rgba(128,128,128,.2)}.gs-search-button span.gs-search-button-on{color:var(--gs-accent,#2563eb);background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 22%,transparent);border-color:var(--gs-accent,#2563eb)}.gs-search-range span{white-space:nowrap;font-family:monospace}@keyframes spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}.gs-loading-overlay{position:absolute;top:0;left:0;right:0;bottom:0;background:color-mix(in srgb,var(--gs-surface,#fff) 70%,transparent);display:flex;align-items:center;justify-content:center;z-index:100;pointer-events:all}.gs-loading-spinner{width:32px;height:32px;border:3px solid color-mix(in srgb,var(--gs-fg,#1f2328) 12%,transparent);border-top-color:var(--gs-accent,#2563eb);border-radius:50%;animation:spin .8s linear infinite}.gs-progress-overlay{position:absolute;top:0;left:0;right:0;bottom:0;z-index:100;pointer-events:all;display:flex;align-items:center;justify-content:center}.gs-progress-box{min-width:240px;padding:16px 18px;border-radius:8px;background:var(--gs-editor-surface,#fff);border:1px solid var(--gs-border,#e3e6ea);box-shadow:0 6px 24px rgba(0,0,0,.28);display:flex;flex-direction:column;gap:10px}.gs-progress-head{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--gs-fg,#1f2328)}.gs-progress-head .gs-loading-spinner{width:15px;height:15px;border-width:2px}.gs-progress-track{height:6px;border-radius:3px;overflow:hidden;background:color-mix(in srgb,var(--gs-fg,#1f2328) 12%,transparent)}.gs-progress-fill{height:100%;border-radius:3px;background:var(--gs-accent,#2563eb);transition:width .1s linear}@keyframes gs-pending-slide{0%{left:-40%}100%{left:100%}}@keyframes gs-pending-pulse{0%{left:0;width:0}50%{left:0;width:100%}100%{left:100%;width:0}}@keyframes gs-flash{0%{opacity:0}20%{opacity:1}100%{opacity:0}}.gs-flash-overlay{position:absolute;inset:0;pointer-events:none;z-index:9999;background:color-mix(in srgb,var(--gs-accent,#2563eb) 15%,transparent);opacity:0}.gs-flash-overlay--active{animation:gs-flash .6s ease-out forwards}`; diff --git a/packages/web/src/styles/root.min.css b/packages/web/src/styles/root.min.css index e9f6df56..6e6e0901 100644 --- a/packages/web/src/styles/root.min.css +++ b/packages/web/src/styles/root.min.css @@ -1 +1 @@ -.gs-root1{display:inline-block;position:relative;border-spacing:0;width:fit-content;max-width:100%;overflow:auto;font-family:"SF Pro Text","SF Pro Icons","Helvetica Neue",Helvetica,Arial,Meiryo,sans-serif;visibility:hidden;opacity:0}.gs-root1.gs-initialized{visibility:visible;opacity:1;transition:opacity .2s ease-in-out}.gs-root1 .gs-main{flex:1;max-width:100%;overflow:hidden;position:relative;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box}.gs-root1 .gs-resizing{width:100%;height:100%;position:absolute;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 8%,transparent);top:0;left:0;z-index:2}.gs-root1 .gs-line-horizontal{width:100%}.gs-root1 .gs-line-vertical{height:100%}.gs-root1 .gs-line{position:relative;top:0;left:0;border:dotted 1px var(--gs-accent,#2563eb);box-sizing:border-box}.gs-root1 .gs-line span{font-size:10px;padding:3px;background-color:var(--gs-accent,#2563eb);color:#fff;margin:0;position:absolute;top:0;left:0}.gs-root1 .gs-scroll-handle{width:100%;height:100%;cursor:cell}.gs-hidden{visibility:hidden;position:absolute;top:0;left:0;width:0;height:0;overflow:hidden;pointer-events:none;z-index:-1}.gs-fixed{position:fixed;top:0;left:0;z-index:1}:where(.gs-root1[data-mode=light],.gs-editor[data-mode=light]){--gs-fg:#1f2328;--gs-muted-fg:#6b7280;--gs-border:#e3e6ea;--gs-bg:rgba(128, 128, 128, 0.07);--gs-canvas:transparent;--gs-surface:#ffffff;--gs-editor-surface:#ffffff;--gs-header-bg:#f4f5f7;--gs-header-fg:#59616b;--gs-accent:#2563eb}.gs-root1{background-color:var(--gs-bg);color:var(--gs-fg)}.gs-root1 .gs-main{background-color:var(--gs-canvas)}.gs-root1 .gs-tabular{background-color:var(--gs-canvas)}.gs-root1 .gs-sheet-body-data{background-color:var(--gs-surface)}.gs-root1 .gs-formula-bar{background-color:var(--gs-header-bg)}.gs-root1 .gs-formula-bar-editor-inner{color:var(--gs-fg)}.gs-root1 .gs-cell{border:solid 1px var(--gs-border)}.gs-root1 .gs-adjuster{background-color:var(--gs-border)}.gs-root1 .gs-tabular-inner{background-color:var(--gs-border)}.gs-root1 .gs-large-editor textarea{color:var(--gs-fg);caret-color:var(--gs-fg)}.gs-root1 .gs-th{background-color:var(--gs-header-bg);color:var(--gs-header-fg)}.gs-root1 .gs-th-top{border-left:solid 1px var(--gs-border)}.gs-root1 .gs-th-top .gs-th-inner{border-top:solid var(--gs-mx-bt,1px) var(--gs-border)}.gs-root1 .gs-th-left{border-top:solid 1px var(--gs-border)}.gs-root1 .gs-th-left .gs-th-inner{border-left:solid var(--gs-mx-bl,1px) var(--gs-border)}.gs-root1 .gs-search-bar{color:color-mix(in srgb,var(--gs-fg) 40%,transparent)}.gs-root1 .gs-search-bar textarea{color:var(--gs-fg);caret-color:var(--gs-fg)}.gs-editor.gs-editing textarea{caret-color:var(--gs-fg)}.gs-editor.gs-editing .gs-editor-hl{background-color:var(--gs-editor-surface);color:var(--gs-fg)}.gs-editor .gs-editor-options{color:var(--gs-fg);background-color:var(--gs-editor-surface);border:solid 1px var(--gs-border)}:where(.gs-root1[data-mode=dark],.gs-editor[data-mode=dark]){--gs-fg:#e4e6e9;--gs-muted-fg:#8b9096;--gs-border:#2c2f34;--gs-bg:rgba(128, 128, 128, 0.07);--gs-canvas:transparent;--gs-surface:#1c1e21;--gs-editor-surface:#1c1e21;--gs-header-bg:#212327;--gs-header-fg:#a6abb2;--gs-accent:#3b82f6}:where(.gs-root1[data-mode=auto],.gs-editor[data-mode=auto]){--gs-fg:#1f2328;--gs-muted-fg:#6b7280;--gs-border:#e3e6ea;--gs-bg:rgba(128, 128, 128, 0.07);--gs-canvas:transparent;--gs-surface:#ffffff;--gs-editor-surface:#ffffff;--gs-header-bg:#f4f5f7;--gs-header-fg:#59616b;--gs-accent:#2563eb}@media (prefers-color-scheme:dark){:where(.gs-root1[data-mode=auto],.gs-editor[data-mode=auto]){--gs-fg:#e4e6e9;--gs-muted-fg:#8b9096;--gs-border:#2c2f34;--gs-bg:rgba(128, 128, 128, 0.07);--gs-canvas:transparent;--gs-surface:#1c1e21;--gs-editor-surface:#1c1e21;--gs-header-bg:#212327;--gs-header-fg:#a6abb2;--gs-accent:#3b82f6}}:where(.gs-root1[data-mode=inherit-light],.gs-editor[data-mode=inherit-light]){--gs-fg:#1f2328;--gs-muted-fg:#6b7280;--gs-border:#e3e6ea;--gs-bg:rgba(128, 128, 128, 0.07);--gs-surface:#ffffff;--gs-editor-surface:#ffffff;--gs-header-bg:#f4f5f7;--gs-header-fg:#59616b;--gs-accent:#2563eb;--gs-bg:transparent;--gs-canvas:transparent;--gs-surface:transparent;--gs-header-bg:transparent}:where(.gs-root1[data-mode=inherit-dark],.gs-editor[data-mode=inherit-dark]){--gs-fg:#e4e6e9;--gs-muted-fg:#8b9096;--gs-border:#2c2f34;--gs-bg:rgba(128, 128, 128, 0.07);--gs-surface:#1c1e21;--gs-editor-surface:#1c1e21;--gs-header-bg:#212327;--gs-header-fg:#a6abb2;--gs-accent:#3b82f6;--gs-bg:transparent;--gs-canvas:transparent;--gs-surface:transparent;--gs-header-bg:transparent}.gs-root1[data-mode=inherit-dark] .gs-adjuster,.gs-root1[data-mode=inherit-dark] .gs-tabular-inner,.gs-root1[data-mode=inherit-light] .gs-adjuster,.gs-root1[data-mode=inherit-light] .gs-tabular-inner{background-color:transparent}.gs-root1[data-mode=inherit-light] .gs-th{background-color:rgba(128,128,128,.1);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}.gs-root1[data-mode=inherit-dark] .gs-th{background-color:rgba(128,128,128,.1);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}.gs-root1[data-gridlines=horizontal] .gs-cell{border-left-color:transparent;border-right-color:transparent}.gs-root1[data-gridlines=none] .gs-cell{border-color:transparent}.gs-root1[data-density=comfortable] .gs-cell-rendered{padding:0 10px}.gs-cell{transition:border-color .2s ease;padding:0;margin:0;box-sizing:border-box;position:relative;font-size:13px;letter-spacing:1px;line-height:24px;cursor:cell;user-select:none;-webkit-user-select:none;-moz-user-select:none}.gs-cell.gs-copying textarea:focus{outline:solid 1px var(--gs-accent,#2563eb)}.gs-cell.gs-selecting{z-index:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 7%,transparent)}.gs-cell.gs-selecting .gs-cell-label{display:block}.gs-cell.gs-choosing{margin-top:-1px;margin-left:-1px;z-index:1}.gs-cell.gs-choosing.gs-editing{color:transparent}.gs-cell.gs-choosing .gs-cell-label{display:block}.gs-cell.gs-pending .gs-cell-rendered{position:relative;overflow:hidden}.gs-cell.gs-pending .gs-cell-rendered::after{content:'';position:absolute;bottom:0;left:0;height:4px;width:40%;border-radius:1px;background:color-mix(in srgb,var(--gs-accent,#2563eb) 65%,transparent);animation:gs-pending-slide 1.4s ease-in-out infinite}.gs-cell .gs-formula-error-triangle{position:absolute;top:0;right:0;border-top:4px solid rgba(200,0,0,.9);border-right:4px solid rgba(200,0,0,.9);border-bottom:4px solid transparent;border-left:4px solid transparent;z-index:2;cursor:help}.gs-cell .gs-cell-label{font-size:10px;font-weight:500;font-style:normal;font-family:inherit;letter-spacing:.2px;line-height:1.4;position:absolute;top:0;right:0;background-color:var(--gs-accent,#2563eb);color:#fff;padding:1px 5px;border-bottom-left-radius:4px;display:none;opacity:.92}.gs-cell .gs-cell-inner-wrap{width:100%;height:100%;position:absolute;top:0;left:0}.gs-cell .gs-cell-inner{width:100%;height:100%;overflow:hidden;display:flex;box-sizing:border-box;border:none!important}.gs-cell .gs-cell-rendered{overflow:hidden;white-space:pre-wrap;cursor:cell;word-wrap:break-word;word-break:break-all;padding:0 6px;width:100%;height:100%}.gs-cell .gs-cell-rendered>*{position:relative}.gs-cell .gs-cell-rendered>.backface{z-index:0}.gs-cell .gs-autofill-drag{background-color:var(--gs-accent,#2563eb);position:absolute;width:7px;height:7px;bottom:0;right:0;cursor:crosshair;z-index:1}.gs-cell.gs-merged-host{z-index:1}.gs-cell.gs-merged-host.gs-selecting{background-color:transparent}.gs-cell.gs-merged-host.gs-selecting .gs-cell-inner-wrap{background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 7%,transparent)}.gs-cell.gs-merged-covered{z-index:0}.gs-th[data-x="1"] .gs-th-inner-wrap{border-left:none}.gs-th[data-y="1"] .gs-th-inner-wrap{border-top:none}.gs-formula-error-tooltip{position:fixed;background-color:rgba(35,8,8,.94);color:#fff;padding:6px 10px;border-radius:4px;border-left:3px solid rgba(220,50,50,.8);font-size:12px;line-height:1.5;max-width:260px;white-space:pre-wrap;word-break:break-word;box-shadow:0 3px 10px rgba(0,0,0,.4);z-index:100;pointer-events:none;letter-spacing:.3px}.gs-menu-modal{width:100%;height:100vh;z-index:12}.gs-label-input-label{font-size:13px;letter-spacing:1px}.gs-menu-divider{background-color:#aaa;padding:0;margin:5px 0;height:1px;list-style-type:none}.gs-menu-btn{position:absolute;background-color:rgba(128,128,128,.3);border:1px solid #ccc;border-radius:50%;cursor:pointer;font-size:12px;font-weight:700;line-height:1;color:#888;width:18px;height:18px;padding:0;display:flex;align-items:center;justify-content:center;opacity:0;transition:opacity .15s ease;z-index:2}.gs-context-menu{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;opacity:.9;transition:opacity .15s ease}.gs-context-menu:hover{opacity:1}.gs-context-menu .gs-menu-items{color:#555;margin:0;padding:0;min-width:250px}.gs-menu-item{padding:5px 10px;list-style-type:none;display:flex}.gs-menu-item.gs-enabled{cursor:pointer}.gs-menu-item.gs-enabled:hover{background-color:#eee}.gs-menu-item.gs-disabled{opacity:.5;cursor:not-allowed}.gs-menu-item .gs-menu-name{font-size:13px;letter-spacing:1px;flex:1}.gs-submenu-parent{position:relative;align-items:center}.gs-submenu-parent .gs-submenu-arrow{margin-left:8px;font-size:11px;opacity:.6}.gs-submenu-flyout{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;opacity:.9;transition:opacity .15s ease;min-width:200px;margin:0;color:#555;opacity:1;list-style-type:none}.gs-submenu-flyout:hover{opacity:1}.gs-menu-shortcut{font-size:10px;line-height:20px;color:#999}.gs-menu-shortcut:before{content:"( "}.gs-menu-shortcut:after{content:" )"}.gs-menu-shortcut .gs-menu-underline{text-decoration:underline}.gs-column-menu{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;opacity:.9;transition:opacity .15s ease}.gs-column-menu:hover{opacity:1}.gs-column-menu ul{color:#555;margin:0;padding:0;min-width:200px}.gs-column-menu .gs-column-menu-sort{align-items:center}.gs-column-menu .gs-column-menu-sort .gs-sort-buttons{display:flex;gap:4px;margin-left:auto}.gs-column-menu .gs-column-menu-sort .gs-sort-btn{font-size:12px;padding:4px 8px;border:1px solid transparent;border-radius:3px;background-color:rgba(180,180,180,.1);cursor:pointer;color:#555;font-weight:700;letter-spacing:.5px}.gs-column-menu .gs-column-menu-sort .gs-sort-btn:hover:not(:disabled){border-color:#555}.gs-column-menu .gs-column-menu-sort .gs-sort-btn:disabled{opacity:.5;cursor:not-allowed}.gs-column-menu .gs-column-menu-label{padding:5px 10px}.gs-column-menu .gs-label-input-row{display:flex;gap:4px;align-items:center}.gs-column-menu .gs-label-input{flex:1;font-size:13px;padding:4px 6px;border:none;border-bottom:1px solid #ccc;border-radius:0;outline:0;min-width:0;width:100px;background-color:transparent;box-shadow:none}.gs-column-menu .gs-label-input:focus{border-bottom-color:var(--gs-accent,#2563eb);outline:0;box-shadow:none}.gs-column-menu .gs-label-apply-btn{font-size:12px;padding:4px 8px;border:1px solid transparent;border-radius:3px;background-color:rgba(180,180,180,.1);cursor:pointer;color:#555;font-weight:700;letter-spacing:.5px}.gs-column-menu .gs-label-apply-btn:hover:not(:disabled){border-color:#555}.gs-column-menu .gs-label-apply-btn:disabled{opacity:.5;cursor:not-allowed}.gs-column-menu .gs-column-menu-filter{padding:5px 10px;list-style-type:none;font-size:13px}.gs-column-menu .gs-filter-header{display:flex;align-items:center;gap:8px}.gs-column-menu .gs-filter-header .gs-filter-add-btn{font-size:12px;padding:3px 9px;border:1px solid transparent;border-radius:3px;background-color:rgba(180,180,180,.1);cursor:pointer;color:#555;letter-spacing:1px}.gs-column-menu .gs-filter-header .gs-filter-add-btn:hover{border-color:#555}.gs-column-menu .gs-filter-mode-toggle{display:flex;gap:6px;margin-left:auto}.gs-column-menu .gs-filter-mode-toggle label{display:flex;align-items:center;gap:3px;font-size:11px;font-weight:700;letter-spacing:.5px;color:#888;cursor:pointer;user-select:none}.gs-column-menu .gs-filter-mode-toggle label input[type=radio]{margin:0;cursor:pointer}.gs-column-menu .gs-filter-mode-toggle label.gs-active{color:var(--gs-accent,#2563eb)}.gs-column-menu .gs-filter-mode-toggle.gs-disabled{opacity:.4;pointer-events:none}.gs-column-menu .gs-filter-conditions{display:flex;flex-direction:column;gap:5px;margin-top:6px;max-height:200px;overflow-y:auto}.gs-column-menu .gs-filter-condition-row{display:flex;gap:4px;align-items:normal}.gs-column-menu .gs-filter-method-select{font-size:12px;padding:4px 4px;border:none;border-bottom:1px solid #ccc;border-radius:0;outline:0;background-color:#fff;box-shadow:none;min-width:40px;max-width:80px;cursor:pointer}.gs-column-menu .gs-filter-method-select:focus{border-bottom-color:var(--gs-accent,#2563eb);outline:0;box-shadow:none}.gs-column-menu .gs-filter-value-input{flex:1;font-size:13px;padding:4px 6px;border:none;border-bottom:1px solid #ccc;border-radius:0;outline:0;min-width:0;width:80px;background-color:transparent;box-shadow:none}.gs-column-menu .gs-filter-value-input:focus{border-bottom-color:var(--gs-accent,#2563eb);outline:0;box-shadow:none}.gs-column-menu .gs-filter-remove-btn{font-size:12px;padding:0;border:none;border-radius:3px;background-color:transparent;cursor:pointer;color:#999;line-height:1;flex-shrink:0}.gs-column-menu .gs-filter-remove-btn:hover{color:#c33}.gs-column-menu .gs-filter-actions{display:flex;gap:4px;margin-top:10px;align-items:center}.gs-column-menu .gs-filter-actions .gs-filter-reset-all-btn{font-size:12px;padding:3px 9px;border:1px solid transparent;border-radius:3px;background-color:transparent;cursor:pointer;color:#c33;font-weight:700;letter-spacing:1px}.gs-column-menu .gs-filter-actions .gs-filter-reset-all-btn:hover{border-color:#c33}.gs-column-menu .gs-filter-actions .gs-filter-actions-right{display:flex;gap:4px;margin-left:auto}.gs-column-menu .gs-filter-actions .gs-filter-reset-btn{font-size:12px;padding:3px 9px;border:1px solid transparent;border-radius:3px;background-color:transparent;cursor:pointer;color:#e08000;font-weight:700;letter-spacing:1px}.gs-column-menu .gs-filter-actions .gs-filter-reset-btn:hover{border-color:#e08000}.gs-column-menu .gs-filter-actions .gs-filter-apply-btn{font-size:12px;padding:3px 6px;border:1px solid transparent;border-radius:3px;background-color:transparent;color:var(--gs-accent,#2563eb);cursor:pointer;font-weight:700;letter-spacing:1px}.gs-column-menu .gs-filter-actions .gs-filter-apply-btn:hover{border-color:var(--gs-accent,#2563eb)}.gs-column-menu-waiting{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:20px 30px;gap:12px;min-width:180px}.gs-column-menu-waiting .gs-waiting-message{font-size:13px;font-weight:700;color:#555;letter-spacing:.5px}.gs-column-menu-waiting .gs-waiting-spinner{width:24px;height:24px;border:3px solid #e0e0e0;border-top-color:var(--gs-accent,#2563eb);border-radius:50%;animation:spin .8s linear infinite}.gs-column-menu-waiting .gs-waiting-cancel-btn{font-size:12px;padding:4px 18px;border:1px solid #c33;border-radius:3px;background-color:transparent;color:#c33;cursor:pointer;font-weight:700;letter-spacing:1px}.gs-column-menu-waiting .gs-waiting-cancel-btn:hover{background-color:#c33;color:#fff}.gs-column-menu-btn{right:4px;top:50%;transform:translateY(-50%)}.gs-column-menu-btn.gs-filtered{opacity:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);border-color:var(--gs-accent,#2563eb);color:var(--gs-accent,#2563eb)}.gs-column-menu-btn.gs-active{opacity:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 18%,transparent);border-color:var(--gs-accent,#2563eb);color:var(--gs-accent,#2563eb)}.gs-th-top:hover .gs-column-menu-btn{opacity:1}.gs-row-menu{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;opacity:.9;transition:opacity .15s ease}.gs-row-menu:hover{opacity:1}.gs-row-menu ul{color:#555;margin:0;padding:0;min-width:200px}.gs-row-fixed-toggle{display:flex;align-items:center;gap:6px}.gs-row-fixed-check{font-size:12px;width:14px;text-align:center;color:transparent}.gs-row-fixed-check.gs-row-fixed-active{color:var(--gs-accent,#2563eb)}.gs-row-menu-btn{top:50%;transform:translateY(-50%);right:2px}.gs-row-menu-btn.gs-active{opacity:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 18%,transparent);border-color:var(--gs-accent,#2563eb);color:var(--gs-accent,#2563eb)}.gs-th-left:hover .gs-row-menu-btn{opacity:1}.gs-corner-menu-btn{bottom:2px;right:2px}.gs-corner-menu-btn:hover{opacity:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 18%,transparent);border-color:var(--gs-accent,#2563eb);color:var(--gs-accent,#2563eb)}.gs-th-left.gs-th-top:hover .gs-corner-menu-btn{opacity:1}.gs-editor-hl{padding:0 2px!important;position:absolute;font-family:monospace,Arial;font-size:12px;line-height:24px;letter-spacing:1px}.gs-formula-bar-editor-inner{position:relative;flex:1;min-width:0;display:flex;align-items:center}.gs-editor{opacity:0;z-index:-1}.gs-editor .gs-editor-inner{position:relative}.gs-editor .gs-editor-hl{box-sizing:content-box;border:solid 2px var(--gs-accent,#2563eb);margin:-2px -1px}.gs-editor textarea{width:100%;padding:0 2px!important;position:absolute;font-size:12px;font-family:monospace,Arial;line-height:24px;letter-spacing:1px;top:0;left:0;border:none;outline:0;background-color:transparent;color:transparent;resize:none;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;overflow:hidden;cursor:default;white-space:pre;height:auto}.gs-editor.gs-editing{z-index:11;opacity:1}.gs-editor.gs-editing .gs-cell-label{pointer-events:none;font-family:inherit;font-weight:500;position:absolute;top:0;right:0;margin-top:-17px;margin-right:-2px;padding:1px 5px;border-top-left-radius:4px;border-top-right-radius:4px;font-size:10px;background-color:var(--gs-accent,#2563eb);color:#fff;z-index:1}.gs-formula-bar{width:100%;position:relative;display:flex;align-items:stretch;box-sizing:border-box;border-style:solid;border-color:var(--gs-border,#e3e6ea);border-width:var(--gs-fb-bt,1px) var(--gs-fb-br,1px) var(--gs-fb-bb,1px) var(--gs-fb-bl,1px);padding:3px 6px;gap:6px}.gs-formula-bar .gs-selecting-address{display:flex;align-items:center;justify-content:center;min-width:38px;padding:0 4px;color:var(--gs-muted-fg,#6b7280);font-size:12px;font-variant-numeric:tabular-nums;text-align:center}.gs-formula-bar[data-spill=true]{background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 6%,var(--gs-header-bg,#f4f5f7))}.gs-formula-bar[data-spill=true] .gs-selecting-address{color:var(--gs-accent,#2563eb);font-style:italic}.gs-formula-bar[data-spill=true] .gs-selecting-address::after{content:"\2196";margin-left:2px;font-style:normal;font-size:9px}.gs-formula-bar .gs-fx{display:flex;align-items:center;justify-content:center;align-self:center;width:26px;height:18px;flex-shrink:0;color:var(--gs-muted-fg,#6b7280);font-style:italic;font-family:inherit;font-weight:400;text-align:center;font-size:13px;letter-spacing:.3px;border-radius:4px;background-color:color-mix(in srgb,var(--gs-fg,#1f2328) 6%,transparent)}.gs-formula-bar .gs-editor-hl{z-index:0;overflow-y:auto;box-sizing:border-box;white-space:pre-wrap;word-break:break-all;text-align:left;line-height:24px}.gs-formula-bar textarea{position:relative;z-index:1;width:100%;vertical-align:bottom;color:transparent;border:none;background-color:transparent;padding:0 2px;box-sizing:border-box;text-align:left;outline:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;font-size:12px;font-family:monospace,Arial;height:24px;line-height:24px;min-height:24px;letter-spacing:1px;resize:vertical;caret-color:var(--gs-fg,#1f2328);white-space:pre-wrap;word-break:break-all}.gs-token-type-INVALID_REF{color:red}.gs-token-type-VALUE.gs-token-entity-type-boolean,.gs-token-type-VALUE.gs-token-entity-type-number{color:#39f}.gs-token-type-VALUE.gs-token-entity-type-string{color:#090}.gs-editor-options{position:fixed;z-index:1000;padding:4px;background:var(--gs-bg,#fff);box-shadow:0 4px 12px rgba(0,0,0,.15);border:1px solid rgba(0,0,0,.1);border-radius:6px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;overflow:visible}.gs-editor-option{position:relative;cursor:pointer;list-style:none;padding:6px 12px;font-size:13px;border-radius:4px;color:#333;margin-bottom:2px}.gs-editor-option-content{display:flex;justify-content:space-between;width:100%;align-items:center}.gs-editor-option-tab{font-size:10px;color:#aaa;margin-left:8px;padding:2px 4px;border:1px solid #ddd;border-radius:3px;background:#f9f9f9}.gs-editor-option:last-child{margin-bottom:0}.gs-editor-option:hover{background-color:#f5f5f5}.gs-editor-option-selected{background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);color:var(--gs-accent,#2563eb);font-weight:500}.gs-editor-option-selected:hover{background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 18%,transparent)}.gs-fn-guide1{position:absolute;top:-4px;left:calc(100% + 8px);background:#fff;border:1px solid rgba(0,0,0,.1);box-shadow:0 4px 16px rgba(0,0,0,.12);border-radius:6px;padding:16px;width:280px;z-index:1000;cursor:default;white-space:normal;color:#333}.gs-fn-guide1-tooltip{margin-bottom:8px;line-height:1.4;font-size:13px}.gs-fn-guide1-example{font-family:monospace;font-weight:600;font-size:13px;margin-bottom:8px;color:#1a1a1a;background:#f5f5f5;padding:6px 8px;border-radius:4px;border:1px solid #eee;display:flex;align-items:center;gap:6px;flex-wrap:wrap}.gs-fn-guide1-desc{font-size:13px;color:#555;margin-bottom:12px;line-height:1.4}.gs-fn-guide1-desc p{margin:0 0 6px 0}.gs-fn-guide1-desc p:last-child{margin-bottom:0}.gs-fn-guide1-args{border-top:1px solid #eee;padding-top:10px}.gs-fn-guide1-arg{margin-bottom:6px;line-height:1.4;font-size:12px}.gs-fn-guide1-arg-name{font-weight:600;color:var(--gs-accent,#2563eb)}.gs-fn-guide1-arg-opt{color:#888;font-size:11px}.gs-fn-guide1-arg-iter{font-weight:600;color:var(--gs-accent,#2563eb)}.gs-fn-guide1-arg-type{color:var(--gs-accent,#2563eb);padding:0 4px;background:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);border-radius:3px;font-size:11px;margin:0 4px}.gs-fn-guide1-arg-desc{color:#666}.gs-fn-guide-category{position:absolute;top:-11px;right:8px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;font-size:11px;font-weight:600;letter-spacing:.5px;text-transform:uppercase;padding:2px 7px;border-radius:4px;background:#e8eaf6;color:#3949ab;border:1px solid #c5cae9;white-space:nowrap}.gs-fn-guide-category.gs-fn-guide-category-math{background:#e3f2fd;color:#1565c0;border-color:#bbdefb}.gs-fn-guide-category.gs-fn-guide-category-statistics{background:#e8f5e9;color:#2e7d32;border-color:#c8e6c9}.gs-fn-guide-category.gs-fn-guide-category-text{background:#fff8e1;color:#f57f17;border-color:#ffecb3}.gs-fn-guide-category.gs-fn-guide-category-time{background:#fce4ec;color:#880e4f;border-color:#f8bbd0}.gs-fn-guide-category.gs-fn-guide-category-lookup{background:#f3e5f5;color:#6a1b9a;border-color:#e1bee7}.gs-fn-guide-category.gs-fn-guide-category-logical{background:#e0f2f1;color:#00695c;border-color:#b2dfdb}.gs-fn-guide-category.gs-fn-guide-category-information{background:#e0f7fa;color:#006064;border-color:#b2ebf2}.gs-fn-guide-category.gs-fn-guide-category-finance{background:#fff3e0;color:#e65100;border-color:#ffe0b2}.gs-fn-guide-category.gs-fn-guide-category-engineering{background:#efebe9;color:#4e342e;border-color:#d7ccc8}.gs-fn-guide-category.gs-fn-guide-category-ai{background:#e8eaf6;color:#3949ab;border-color:#c5cae9}.gs-fn-guide-category.gs-fn-guide-category-other{background:#f5f5f5;color:#616161;border-color:#e0e0e0}.gs-editor-portal{display:contents}.gs-editor-portal[data-mode=dark] .gs-editor-options,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-options,.gs-editor[data-mode=dark] .gs-editor-options,.gs-editor[data-mode=inherit-dark] .gs-editor-options{background:#252526;border-color:#454545;box-shadow:0 4px 12px rgba(0,0,0,.5)}.gs-editor-portal[data-mode=dark] .gs-editor-option,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option,.gs-editor[data-mode=dark] .gs-editor-option,.gs-editor[data-mode=inherit-dark] .gs-editor-option{color:#ccc}.gs-editor-portal[data-mode=dark] .gs-editor-option:hover,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option:hover,.gs-editor[data-mode=dark] .gs-editor-option:hover,.gs-editor[data-mode=inherit-dark] .gs-editor-option:hover{background-color:#333}.gs-editor-portal[data-mode=dark] .gs-editor-option-selected,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option-selected,.gs-editor[data-mode=dark] .gs-editor-option-selected,.gs-editor[data-mode=inherit-dark] .gs-editor-option-selected{background-color:#094771;color:#fff}.gs-editor-portal[data-mode=dark] .gs-editor-option-selected:hover,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option-selected:hover,.gs-editor[data-mode=dark] .gs-editor-option-selected:hover,.gs-editor[data-mode=inherit-dark] .gs-editor-option-selected:hover{background-color:#0d5a8f}.gs-editor-portal[data-mode=dark] .gs-editor-option-tab,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option-tab,.gs-editor[data-mode=dark] .gs-editor-option-tab,.gs-editor[data-mode=inherit-dark] .gs-editor-option-tab{color:#777;background:#333;border-color:#444}.gs-editor-portal[data-mode=dark] .gs-fn-guide1,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1,.gs-editor[data-mode=dark] .gs-fn-guide1,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1{background:#252526;border-color:#454545;color:#ccc}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-example,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-example,.gs-editor[data-mode=dark] .gs-fn-guide1-example,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-example{background:#1e1e1e;border-color:#333;color:#d4d4d4}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-desc,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-desc,.gs-editor[data-mode=dark] .gs-fn-guide1-desc,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-desc{color:#aaa}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-args,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-args,.gs-editor[data-mode=dark] .gs-fn-guide1-args,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-args{border-color:#333}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-iter,.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-name,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-iter,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-name,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-iter,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-name,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-iter,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-name{color:#4fc1ff}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-opt,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-opt,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-opt,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-opt{color:#777}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-type,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-type,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-type,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-type{background:#094771;color:#4fc1ff}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-desc,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-desc,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-desc,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-desc{color:#999}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category,.gs-editor[data-mode=dark] .gs-fn-guide-category,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category{background:#2a2d3e;color:#7986cb;border-color:#3d4166}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-math,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-math,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-math,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-math{background:#0d2137;color:#64b5f6;border-color:#1a3a5c}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-statistics,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-statistics,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-statistics,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-statistics{background:#0d2218;color:#66bb6a;border-color:#1a3d2a}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-text,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-text,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-text,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-text{background:#2e2200;color:#ffd54f;border-color:#4d3900}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-time,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-time,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-time,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-time{background:#2d0d1e;color:#f48fb1;border-color:#4d1a33}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-lookup,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-lookup,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-lookup,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-lookup{background:#260d33;color:#ce93d8;border-color:#3d1a54}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-logical,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-logical,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-logical,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-logical{background:#0d2421;color:#4db6ac;border-color:#1a3d39}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-information,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-information,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-information,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-information{background:#0d2426;color:#4dd0e1;border-color:#1a3d40}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-finance,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-finance,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-finance,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-finance{background:#2e1500;color:#ffb74d;border-color:#4d2800}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-engineering,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-engineering,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-engineering,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-engineering{background:#1e1714;color:#bcaaa4;border-color:#332c28}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-ai,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-ai,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-ai,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-ai{background:#10142e;color:#7986cb;border-color:#232a52}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-other,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-other,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-other,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-other{background:#1e1e1e;color:#9e9e9e;border-color:#333}.gs-editor-portal[data-mode=dark] .gs-fn-guide2,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2,.gs-editor[data-mode=dark] .gs-fn-guide2,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2{background:#252526;border-color:#454545;box-shadow:0 4px 12px rgba(0,0,0,.5);color:#ccc}.gs-editor-portal[data-mode=dark] .gs-fn-guide2-name,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2-name,.gs-editor[data-mode=dark] .gs-fn-guide2-name,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2-name{color:#dfdbdb;background:#333;border-color:#444}.gs-editor-portal[data-mode=dark] .gs-fn-guide2 .gs-active-arg,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2 .gs-active-arg,.gs-editor[data-mode=dark] .gs-fn-guide2 .gs-active-arg,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2 .gs-active-arg{color:#fff;background-color:#094771}.gs-editor-portal[data-mode=dark] .gs-fn-guide2-arg-type,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2-arg-type,.gs-editor[data-mode=dark] .gs-fn-guide2-arg-type,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2-arg-type{background:#094771;color:#4fc1ff}.gs-editor-portal[data-mode=dark] .gs-fn-guide2-desc,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2-desc,.gs-editor[data-mode=dark] .gs-fn-guide2-desc,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2-desc{color:#aaa;border-top-color:#333}.gs-fn-guide2{position:fixed;left:0;background:#fff;border:1px solid rgba(0,0,0,.1);box-shadow:0 4px 16px rgba(0,0,0,.12);border-radius:6px;padding:12px 16px;width:280px;z-index:1000;cursor:default;white-space:normal;color:#333;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;transition:opacity .1s ease-in-out}.gs-fn-guide2.gs-fn-guide2-hidden{opacity:0!important;pointer-events:none!important}.gs-fn-guide2-name{font-family:monospace;font-weight:700;font-size:13px;color:#1a1a1a;background:#f5f5f5;padding:6px 8px;border-radius:4px;border:1px solid #eee;display:flex;align-items:center;gap:6px;flex-wrap:wrap;width:100%;box-sizing:border-box;margin-bottom:8px}.gs-fn-guide2-args-inline{font-size:13px;font-family:monospace;line-height:1.5;margin-bottom:8px;color:#666}.gs-fn-guide2-args-inline span{transition:all .2s ease-in-out}.gs-fn-guide2 .gs-active-arg{font-weight:700;color:var(--gs-accent,#2563eb);background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);padding:2px 4px;margin:0 -4px;border-radius:4px}.gs-fn-guide2-arg-type{color:var(--gs-accent,#2563eb);padding:0 4px;background:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);border-radius:3px;font-size:11px;margin:0 4px}.gs-fn-guide2-desc{font-size:12px;color:#555;line-height:1.4;border-top:1px solid #eee;padding-top:8px;margin-top:4px}.gs-fn-guide2-desc p{margin:0}.gs-fn-guide2-desc-more{font-style:italic;color:#888;margin-top:4px!important;font-size:11px}.gs-adjuster{padding:0}.gs-table{margin:0}.gs-tabular{overflow:auto;overflow-anchor:none;display:flex;box-sizing:border-box;position:relative}.gs-root1[data-matrix-align=both] .gs-tabular,.gs-root1[data-matrix-align=horizontal] .gs-tabular{justify-content:safe center}.gs-root1[data-matrix-align=both] .gs-tabular,.gs-root1[data-matrix-align=vertical] .gs-tabular{align-items:safe center}.gs-tabular-inner{flex:0 0 auto;position:relative;overflow:hidden;overflow:clip;box-sizing:border-box;border-right:solid var(--gs-mx-br,1px) var(--gs-border,#e3e6ea);border-bottom:solid var(--gs-mx-bb,1px) var(--gs-border,#e3e6ea)}.gs-tabular-inner>table{table-layout:fixed;border-collapse:collapse;border-spacing:0}.gs-main[data-overflow-x=true] .gs-tabular-inner{border-right-width:0}.gs-main[data-overflow-y=true] .gs-tabular-inner{border-bottom-width:0}.gs-main::after{content:'';position:absolute;inset:0;pointer-events:none;z-index:3;border:0 solid var(--gs-border,#e3e6ea)}.gs-main[data-overflow-x=true]::after{border-right-width:var(--gs-mx-br,1px)}.gs-main[data-overflow-y=true]::after{border-bottom-width:var(--gs-mx-bb,1px)}.gs-th{z-index:2;padding:0;position:sticky;font-size:13px;font-weight:400;box-sizing:border-box;vertical-align:top}.gs-th .gs-resizer{position:absolute;border-color:transparent;box-sizing:border-box;z-index:2}.gs-th .gs-resizer:hover{background-color:var(--gs-accent,#2563eb)}.gs-th .gs-resizer.gs-protected{display:none}.gs-th-inner{height:100%;box-sizing:border-box;vertical-align:middle;overflow:hidden;display:flex;align-items:center;justify-content:center}.gs-th-inner-wrap{height:100%;box-sizing:border-box;background-color:transparent}.gs-th-top{top:0;overflow:hidden}.gs-th-top .gs-resizer{top:0;right:0;width:3px;cursor:e-resize}.gs-th-top .gs-resizer.gs-dragging{border-right-style:dotted;height:1000000px!important;cursor:e-resize}.gs-th-left{left:0;overflow:hidden;min-width:30px;border-top:solid 1px var(--gs-border,#e3e6ea)}.gs-th-left .gs-resizer{left:0;bottom:0;height:3px;cursor:n-resize}.gs-th-left .gs-resizer.gs-dragging{border-bottom-style:dotted;width:1000000px!important;cursor:n-resize}.gs-th-top.gs-th-left{top:0;left:0;z-index:3;border:none!important}.gs-th-left.gs-filter-fixed .gs-th-inner::before{content:'‹\00a0'}.gs-th-left.gs-sort-fixed .gs-th-inner::after{content:'\00a0›'}.gs-col-addr{position:absolute;top:2px;right:4px;font-size:9px;opacity:.5;line-height:1;letter-spacing:.3px;pointer-events:none}.gs-search-bar{width:100%;display:flex;align-items:center;padding:3px 0;border-top:solid 1px rgba(128,128,128,.3);border-left:solid 1px rgba(128,128,128,.3);border-right:solid 1px rgba(128,128,128,.3);border-bottom:solid 1px rgba(128,128,128,.3);box-sizing:border-box;background-color:rgba(200,50,0,.2)}.gs-search-bar.gs-search-found{background-color:rgba(0,200,100,.2)}.gs-search-bar .gs-search-bar-inner{border-left:solid 1px rgba(128,128,128,.5)}.gs-search-bar .gs-search-bar-icon{border-left:solid 1px rgba(128,128,128,.3);display:flex;align-items:center;justify-content:center;width:30px;flex-shrink:0}.gs-search-bar .gs-search-input-wrapper{flex-grow:1;position:relative;display:flex;align-items:center;height:100%}.gs-search-bar .gs-search-input-ghost{position:absolute;left:2px;right:2px;top:0;bottom:0;pointer-events:none;font-size:12px;font-family:monospace,Arial;line-height:24px;letter-spacing:1px;white-space:pre-wrap;word-break:break-all;color:transparent;overflow:hidden}.gs-search-bar .gs-search-input-ghost .gs-search-ghost-hint{color:#aaa}.gs-search-bar textarea{background-color:transparent;border:none;padding:0 2px;box-sizing:border-box;outline:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;font-size:12px;font-family:monospace,Arial;height:24px;line-height:24px;min-height:24px;letter-spacing:1px;caret-color:rgba(128,128,128);white-space:pre-wrap;word-break:break-all;flex-grow:1;width:100%;resize:none}.gs-search-progress{color:#999;font-size:13px;width:60px;flex-shrink:0;white-space:nowrap;text-align:center}.gs-search-close{cursor:pointer;display:flex;align-items:center;justify-content:center;width:24px;flex-shrink:0}.gs-search-buttons{display:flex;align-items:center;white-space:nowrap;flex-shrink:0}.gs-search-button{display:inline-flex;cursor:pointer;margin:0 2px}.gs-search-button span{display:inline-block;font-size:11px;padding:3px 5px;background-color:rgba(128,128,128,.1);border:1px solid rgba(128,128,128,.3);border-radius:3px;transition:all .15s ease;line-height:1}.gs-search-button span:hover{background-color:rgba(128,128,128,.2)}.gs-search-button span.gs-search-button-on{color:var(--gs-accent,#2563eb);background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 22%,transparent);border-color:var(--gs-accent,#2563eb)}.gs-search-range span{white-space:nowrap;font-family:monospace}@keyframes spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}.gs-loading-overlay{position:absolute;top:0;left:0;right:0;bottom:0;background:color-mix(in srgb,var(--gs-surface,#fff) 70%,transparent);display:flex;align-items:center;justify-content:center;z-index:100;pointer-events:all}.gs-loading-spinner{width:32px;height:32px;border:3px solid color-mix(in srgb,var(--gs-fg,#1f2328) 12%,transparent);border-top-color:var(--gs-accent,#2563eb);border-radius:50%;animation:spin .8s linear infinite}.gs-progress-overlay{position:absolute;top:0;left:0;right:0;bottom:0;z-index:100;pointer-events:all;display:flex;align-items:center;justify-content:center}.gs-progress-box{min-width:240px;padding:16px 18px;border-radius:8px;background:var(--gs-editor-surface,#fff);border:1px solid var(--gs-border,#e3e6ea);box-shadow:0 6px 24px rgba(0,0,0,.28);display:flex;flex-direction:column;gap:10px}.gs-progress-head{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--gs-fg,#1f2328)}.gs-progress-head .gs-loading-spinner{width:15px;height:15px;border-width:2px}.gs-progress-track{height:6px;border-radius:3px;overflow:hidden;background:color-mix(in srgb,var(--gs-fg,#1f2328) 12%,transparent)}.gs-progress-fill{height:100%;border-radius:3px;background:var(--gs-accent,#2563eb);transition:width .1s linear}@keyframes gs-pending-slide{0%{left:-40%}100%{left:100%}}@keyframes gs-pending-pulse{0%{left:0;width:0}50%{left:0;width:100%}100%{left:100%;width:0}}@keyframes gs-flash{0%{opacity:0}20%{opacity:1}100%{opacity:0}}.gs-flash-overlay{position:absolute;inset:0;pointer-events:none;z-index:9999;background:color-mix(in srgb,var(--gs-accent,#2563eb) 15%,transparent);opacity:0}.gs-flash-overlay--active{animation:gs-flash .6s ease-out forwards} \ No newline at end of file +.gs-root1{display:inline-block;position:relative;border-spacing:0;width:fit-content;max-width:100%;overflow:auto;font-family:"SF Pro Text","SF Pro Icons","Helvetica Neue",Helvetica,Arial,Meiryo,sans-serif;visibility:hidden;opacity:0}.gs-root1.gs-initialized{visibility:visible;opacity:1;transition:opacity .2s ease-in-out}.gs-root1 .gs-main{flex:1;max-width:100%;overflow:hidden;position:relative;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box}.gs-root1 .gs-resizing{width:100%;height:100%;position:absolute;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 8%,transparent);top:0;left:0;z-index:2}.gs-root1 .gs-line-horizontal{width:100%}.gs-root1 .gs-line-vertical{height:100%}.gs-root1 .gs-line{position:relative;top:0;left:0;border:dotted 1px var(--gs-accent,#2563eb);box-sizing:border-box}.gs-root1 .gs-line span{font-size:10px;padding:3px;background-color:var(--gs-accent,#2563eb);color:#fff;margin:0;position:absolute;top:0;left:0}.gs-root1 .gs-scroll-handle{width:100%;height:100%;cursor:cell}.gs-hidden{visibility:hidden;position:absolute;top:0;left:0;width:0;height:0;overflow:hidden;pointer-events:none;z-index:-1}.gs-fixed{position:fixed;top:0;left:0;z-index:1}:where(.gs-root1[data-mode=light],.gs-editor[data-mode=light]){--gs-fg:#1f2328;--gs-muted-fg:#6b7280;--gs-border:#e3e6ea;--gs-bg:rgba(128, 128, 128, 0.07);--gs-canvas:transparent;--gs-surface:#ffffff;--gs-editor-surface:#ffffff;--gs-header-bg:#f4f5f7;--gs-header-fg:#59616b;--gs-accent:#2563eb}.gs-root1{background-color:var(--gs-bg);color:var(--gs-fg)}.gs-root1 .gs-main{background-color:var(--gs-canvas)}.gs-root1 .gs-tabular{background-color:var(--gs-canvas)}.gs-root1 .gs-sheet-body-data{background-color:var(--gs-surface)}.gs-root1 .gs-formula-bar{background-color:var(--gs-header-bg)}.gs-root1 .gs-formula-bar-editor-inner{color:var(--gs-fg)}.gs-root1 .gs-cell{border:solid 1px var(--gs-border)}.gs-root1 .gs-adjuster{background-color:var(--gs-border)}.gs-root1 .gs-tabular-inner{background-color:var(--gs-border)}.gs-root1 .gs-large-editor textarea{color:var(--gs-fg);caret-color:var(--gs-fg)}.gs-root1 .gs-th{background-color:var(--gs-header-bg);color:var(--gs-header-fg)}.gs-root1 .gs-th-top{border-left:solid 1px var(--gs-border)}.gs-root1 .gs-th-top .gs-th-inner{border-top:solid var(--gs-mx-bt,1px) var(--gs-border)}.gs-root1 .gs-th-left{border-top:solid 1px var(--gs-border)}.gs-root1 .gs-th-left .gs-th-inner{border-left:solid var(--gs-mx-bl,1px) var(--gs-border)}.gs-root1 .gs-search-bar{color:color-mix(in srgb,var(--gs-fg) 40%,transparent)}.gs-root1 .gs-search-bar textarea{color:var(--gs-fg);caret-color:var(--gs-fg)}.gs-editor.gs-editing textarea{caret-color:var(--gs-fg)}.gs-editor.gs-editing .gs-editor-hl{background-color:var(--gs-editor-surface);color:var(--gs-fg)}.gs-editor .gs-editor-options{color:var(--gs-fg);background-color:var(--gs-editor-surface);border:solid 1px var(--gs-border)}:where(.gs-root1[data-mode=dark],.gs-editor[data-mode=dark]){--gs-fg:#e4e6e9;--gs-muted-fg:#8b9096;--gs-border:#2c2f34;--gs-bg:rgba(128, 128, 128, 0.07);--gs-canvas:transparent;--gs-surface:#1c1e21;--gs-editor-surface:#1c1e21;--gs-header-bg:#212327;--gs-header-fg:#a6abb2;--gs-accent:#3b82f6}:where(.gs-root1[data-mode=auto],.gs-editor[data-mode=auto]){--gs-fg:#1f2328;--gs-muted-fg:#6b7280;--gs-border:#e3e6ea;--gs-bg:rgba(128, 128, 128, 0.07);--gs-canvas:transparent;--gs-surface:#ffffff;--gs-editor-surface:#ffffff;--gs-header-bg:#f4f5f7;--gs-header-fg:#59616b;--gs-accent:#2563eb}@media (prefers-color-scheme:dark){:where(.gs-root1[data-mode=auto],.gs-editor[data-mode=auto]){--gs-fg:#e4e6e9;--gs-muted-fg:#8b9096;--gs-border:#2c2f34;--gs-bg:rgba(128, 128, 128, 0.07);--gs-canvas:transparent;--gs-surface:#1c1e21;--gs-editor-surface:#1c1e21;--gs-header-bg:#212327;--gs-header-fg:#a6abb2;--gs-accent:#3b82f6}}:where(.gs-root1[data-mode=inherit-light],.gs-editor[data-mode=inherit-light]){--gs-fg:#1f2328;--gs-muted-fg:#6b7280;--gs-border:#e3e6ea;--gs-bg:rgba(128, 128, 128, 0.07);--gs-surface:#ffffff;--gs-editor-surface:#ffffff;--gs-header-bg:#f4f5f7;--gs-header-fg:#59616b;--gs-accent:#2563eb;--gs-bg:transparent;--gs-canvas:transparent;--gs-surface:transparent;--gs-header-bg:transparent}:where(.gs-root1[data-mode=inherit-dark],.gs-editor[data-mode=inherit-dark]){--gs-fg:#e4e6e9;--gs-muted-fg:#8b9096;--gs-border:#2c2f34;--gs-bg:rgba(128, 128, 128, 0.07);--gs-surface:#1c1e21;--gs-editor-surface:#1c1e21;--gs-header-bg:#212327;--gs-header-fg:#a6abb2;--gs-accent:#3b82f6;--gs-bg:transparent;--gs-canvas:transparent;--gs-surface:transparent;--gs-header-bg:transparent}.gs-root1[data-mode=inherit-dark] .gs-adjuster,.gs-root1[data-mode=inherit-dark] .gs-tabular-inner,.gs-root1[data-mode=inherit-light] .gs-adjuster,.gs-root1[data-mode=inherit-light] .gs-tabular-inner{background-color:transparent}.gs-root1[data-mode=inherit-light] .gs-th{background-color:rgba(128,128,128,.1);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}.gs-root1[data-mode=inherit-dark] .gs-th{background-color:rgba(128,128,128,.1);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}.gs-root1[data-gridlines=horizontal] .gs-cell{border-left-color:transparent;border-right-color:transparent}.gs-root1[data-gridlines=none] .gs-cell{border-color:transparent}.gs-root1[data-density=comfortable] .gs-cell-rendered{padding:0 10px}.gs-cell{transition:border-color .2s ease;padding:0;margin:0;box-sizing:border-box;position:relative;font-size:13px;letter-spacing:1px;line-height:24px;cursor:cell;user-select:none;-webkit-user-select:none;-moz-user-select:none}.gs-cell.gs-copying textarea:focus{outline:solid 1px var(--gs-accent,#2563eb)}.gs-cell.gs-selecting{z-index:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 7%,transparent)}.gs-cell.gs-selecting .gs-cell-label{display:block}.gs-cell.gs-choosing{margin-top:-1px;margin-left:-1px;z-index:1}.gs-cell.gs-choosing.gs-editing{color:transparent}.gs-cell.gs-choosing .gs-cell-label{display:block}.gs-cell.gs-pending .gs-cell-rendered{position:relative;overflow:hidden}.gs-cell.gs-pending .gs-cell-rendered::after{content:'';position:absolute;bottom:0;left:0;height:4px;width:40%;border-radius:1px;background:color-mix(in srgb,var(--gs-accent,#2563eb) 65%,transparent);animation:gs-pending-slide 1.4s ease-in-out infinite}.gs-cell .gs-formula-error-triangle{position:absolute;top:0;right:0;border-top:4px solid rgba(200,0,0,.9);border-right:4px solid rgba(200,0,0,.9);border-bottom:4px solid transparent;border-left:4px solid transparent;z-index:2;cursor:help}.gs-cell .gs-cell-label{font-size:10px;font-weight:500;font-style:normal;font-family:inherit;letter-spacing:.2px;line-height:1.4;position:absolute;top:0;right:0;background-color:var(--gs-accent,#2563eb);color:#fff;padding:1px 5px;border-bottom-left-radius:4px;display:none;opacity:.92}.gs-cell .gs-cell-inner-wrap{width:100%;height:100%;position:absolute;top:0;left:0}.gs-cell .gs-cell-inner{width:100%;height:100%;overflow:hidden;display:flex;box-sizing:border-box;border:none!important}.gs-cell .gs-cell-rendered{overflow:hidden;white-space:pre-wrap;cursor:cell;word-wrap:break-word;word-break:break-all;padding:0 6px;width:100%;height:100%}.gs-cell .gs-cell-rendered>*{position:relative}.gs-cell .gs-cell-rendered>.backface{z-index:0}.gs-cell .gs-autofill-drag{background-color:var(--gs-accent,#2563eb);position:absolute;width:7px;height:7px;bottom:0;right:0;cursor:crosshair;z-index:1}.gs-cell.gs-merged-host{z-index:1}.gs-cell.gs-merged-host.gs-selecting{background-color:transparent}.gs-cell.gs-merged-host.gs-selecting .gs-cell-inner-wrap{background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 7%,transparent)}.gs-cell.gs-merged-covered{z-index:0}.gs-th[data-x="1"] .gs-th-inner-wrap{border-left:none}.gs-th[data-y="1"] .gs-th-inner-wrap{border-top:none}.gs-formula-error-tooltip{position:fixed;background-color:rgba(35,8,8,.94);color:#fff;padding:6px 10px;border-radius:4px;border-left:3px solid rgba(220,50,50,.8);font-size:12px;line-height:1.5;max-width:260px;white-space:pre-wrap;word-break:break-word;box-shadow:0 3px 10px rgba(0,0,0,.4);z-index:100;pointer-events:none;letter-spacing:.3px}.gs-menu-modal{width:100%;height:100vh;z-index:12}.gs-label-input-label{font-size:13px;letter-spacing:1px}.gs-menu-divider{background-color:#aaa;padding:0;margin:5px 0;height:1px;list-style-type:none}.gs-menu-btn{position:absolute;background-color:rgba(128,128,128,.3);border:1px solid #ccc;border-radius:50%;cursor:pointer;font-size:12px;font-weight:700;line-height:1;color:#888;width:18px;height:18px;padding:0;display:flex;align-items:center;justify-content:center;opacity:0;transition:opacity .15s ease;z-index:2}.gs-context-menu{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;opacity:.9;transition:opacity .15s ease}.gs-context-menu:hover{opacity:1}.gs-context-menu .gs-menu-items{color:#555;margin:0;padding:0;min-width:250px}.gs-menu-item{padding:5px 10px;list-style-type:none;display:flex}.gs-menu-item.gs-enabled{cursor:pointer}.gs-menu-item.gs-enabled:hover{background-color:#eee}.gs-menu-item.gs-disabled{opacity:.5;cursor:not-allowed}.gs-menu-item .gs-menu-name{font-size:13px;letter-spacing:1px;flex:1}.gs-submenu-parent{position:relative;align-items:center}.gs-submenu-parent .gs-submenu-arrow{margin-left:8px;font-size:11px;opacity:.6}.gs-submenu-flyout{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;opacity:.9;transition:opacity .15s ease;min-width:200px;margin:0;color:#555;opacity:1;list-style-type:none}.gs-submenu-flyout:hover{opacity:1}.gs-menu-shortcut{font-size:10px;line-height:20px;color:#999}.gs-menu-shortcut:before{content:"( "}.gs-menu-shortcut:after{content:" )"}.gs-menu-shortcut .gs-menu-underline{text-decoration:underline}.gs-column-menu{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;opacity:.9;transition:opacity .15s ease}.gs-column-menu:hover{opacity:1}.gs-column-menu ul{color:#555;margin:0;padding:0;min-width:200px}.gs-column-menu .gs-column-menu-sort{align-items:center}.gs-column-menu .gs-column-menu-sort .gs-sort-buttons{display:flex;gap:4px;margin-left:auto}.gs-column-menu .gs-column-menu-sort .gs-sort-btn{font-size:12px;padding:4px 8px;border:1px solid transparent;border-radius:3px;background-color:rgba(180,180,180,.1);cursor:pointer;color:#555;font-weight:700;letter-spacing:.5px}.gs-column-menu .gs-column-menu-sort .gs-sort-btn:hover:not(:disabled){border-color:#555}.gs-column-menu .gs-column-menu-sort .gs-sort-btn:disabled{opacity:.5;cursor:not-allowed}.gs-column-menu .gs-column-menu-label{padding:5px 10px}.gs-column-menu .gs-label-input-row{display:flex;gap:4px;align-items:center}.gs-column-menu .gs-label-input{flex:1;font-size:13px;padding:4px 6px;border:none;border-bottom:1px solid #ccc;border-radius:0;outline:0;min-width:0;width:100px;background-color:transparent;box-shadow:none}.gs-column-menu .gs-label-input:focus{border-bottom-color:var(--gs-accent,#2563eb);outline:0;box-shadow:none}.gs-column-menu .gs-label-apply-btn{font-size:12px;padding:4px 8px;border:1px solid transparent;border-radius:3px;background-color:rgba(180,180,180,.1);cursor:pointer;color:#555;font-weight:700;letter-spacing:.5px}.gs-column-menu .gs-label-apply-btn:hover:not(:disabled){border-color:#555}.gs-column-menu .gs-label-apply-btn:disabled{opacity:.5;cursor:not-allowed}.gs-column-menu .gs-column-menu-filter{padding:5px 10px;list-style-type:none;font-size:13px}.gs-column-menu .gs-filter-header{display:flex;align-items:center;gap:8px}.gs-column-menu .gs-filter-header .gs-filter-add-btn{font-size:12px;padding:3px 9px;border:1px solid transparent;border-radius:3px;background-color:rgba(180,180,180,.1);cursor:pointer;color:#555;letter-spacing:1px}.gs-column-menu .gs-filter-header .gs-filter-add-btn:hover{border-color:#555}.gs-column-menu .gs-filter-mode-toggle{display:flex;gap:6px;margin-left:auto}.gs-column-menu .gs-filter-mode-toggle label{display:flex;align-items:center;gap:3px;font-size:11px;font-weight:700;letter-spacing:.5px;color:#888;cursor:pointer;user-select:none}.gs-column-menu .gs-filter-mode-toggle label input[type=radio]{margin:0;cursor:pointer}.gs-column-menu .gs-filter-mode-toggle label.gs-active{color:var(--gs-accent,#2563eb)}.gs-column-menu .gs-filter-mode-toggle.gs-disabled{opacity:.4;pointer-events:none}.gs-column-menu .gs-filter-conditions{display:flex;flex-direction:column;gap:5px;margin-top:6px;max-height:200px;overflow-y:auto}.gs-column-menu .gs-filter-condition-row{display:flex;gap:4px;align-items:normal}.gs-column-menu .gs-filter-method-select{font-size:12px;padding:4px 4px;border:none;border-bottom:1px solid #ccc;border-radius:0;outline:0;background-color:#fff;box-shadow:none;min-width:40px;max-width:80px;cursor:pointer}.gs-column-menu .gs-filter-method-select:focus{border-bottom-color:var(--gs-accent,#2563eb);outline:0;box-shadow:none}.gs-column-menu .gs-filter-value-input{flex:1;font-size:13px;padding:4px 6px;border:none;border-bottom:1px solid #ccc;border-radius:0;outline:0;min-width:0;width:80px;background-color:transparent;box-shadow:none}.gs-column-menu .gs-filter-value-input:focus{border-bottom-color:var(--gs-accent,#2563eb);outline:0;box-shadow:none}.gs-column-menu .gs-filter-remove-btn{font-size:12px;padding:0;border:none;border-radius:3px;background-color:transparent;cursor:pointer;color:#999;line-height:1;flex-shrink:0}.gs-column-menu .gs-filter-remove-btn:hover{color:#c33}.gs-column-menu .gs-filter-actions{display:flex;gap:4px;margin-top:10px;align-items:center}.gs-column-menu .gs-filter-actions .gs-filter-reset-all-btn{font-size:12px;padding:3px 9px;border:1px solid transparent;border-radius:3px;background-color:transparent;cursor:pointer;color:#c33;font-weight:700;letter-spacing:1px}.gs-column-menu .gs-filter-actions .gs-filter-reset-all-btn:hover{border-color:#c33}.gs-column-menu .gs-filter-actions .gs-filter-actions-right{display:flex;gap:4px;margin-left:auto}.gs-column-menu .gs-filter-actions .gs-filter-reset-btn{font-size:12px;padding:3px 9px;border:1px solid transparent;border-radius:3px;background-color:transparent;cursor:pointer;color:#e08000;font-weight:700;letter-spacing:1px}.gs-column-menu .gs-filter-actions .gs-filter-reset-btn:hover{border-color:#e08000}.gs-column-menu .gs-filter-actions .gs-filter-apply-btn{font-size:12px;padding:3px 6px;border:1px solid transparent;border-radius:3px;background-color:transparent;color:var(--gs-accent,#2563eb);cursor:pointer;font-weight:700;letter-spacing:1px}.gs-column-menu .gs-filter-actions .gs-filter-apply-btn:hover{border-color:var(--gs-accent,#2563eb)}.gs-column-menu-waiting{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:20px 30px;gap:12px;min-width:180px}.gs-column-menu-waiting .gs-waiting-message{font-size:13px;font-weight:700;color:#555;letter-spacing:.5px}.gs-column-menu-waiting .gs-waiting-spinner{width:24px;height:24px;border:3px solid #e0e0e0;border-top-color:var(--gs-accent,#2563eb);border-radius:50%;animation:spin .8s linear infinite}.gs-column-menu-waiting .gs-waiting-cancel-btn{font-size:12px;padding:4px 18px;border:1px solid #c33;border-radius:3px;background-color:transparent;color:#c33;cursor:pointer;font-weight:700;letter-spacing:1px}.gs-column-menu-waiting .gs-waiting-cancel-btn:hover{background-color:#c33;color:#fff}.gs-column-menu-btn{right:4px;top:50%;transform:translateY(-50%)}.gs-column-menu-btn.gs-filtered{opacity:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);border-color:var(--gs-accent,#2563eb);color:var(--gs-accent,#2563eb)}.gs-column-menu-btn.gs-active{opacity:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 18%,transparent);border-color:var(--gs-accent,#2563eb);color:var(--gs-accent,#2563eb)}.gs-th-top:hover .gs-column-menu-btn{opacity:1}.gs-row-menu{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;opacity:.9;transition:opacity .15s ease}.gs-row-menu:hover{opacity:1}.gs-row-menu ul{color:#555;margin:0;padding:0;min-width:200px}.gs-row-fixed-toggle{display:flex;align-items:center;gap:6px}.gs-row-fixed-check{font-size:12px;width:14px;text-align:center;color:transparent}.gs-row-fixed-check.gs-row-fixed-active{color:var(--gs-accent,#2563eb)}.gs-row-menu-btn{top:50%;transform:translateY(-50%);right:2px}.gs-row-menu-btn.gs-active{opacity:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 18%,transparent);border-color:var(--gs-accent,#2563eb);color:var(--gs-accent,#2563eb)}.gs-th-left:hover .gs-row-menu-btn{opacity:1}.gs-corner-menu-btn{bottom:2px;right:2px}.gs-corner-menu-btn:hover{opacity:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 18%,transparent);border-color:var(--gs-accent,#2563eb);color:var(--gs-accent,#2563eb)}.gs-th-left.gs-th-top:hover .gs-corner-menu-btn{opacity:1}.gs-editor-hl{padding:0 2px!important;position:absolute;font-family:monospace,Arial;font-size:12px;line-height:24px;letter-spacing:1px}.gs-formula-bar-editor-inner{position:relative;flex:1;min-width:0;display:flex;align-items:center}.gs-editor{opacity:0;z-index:-1}.gs-editor .gs-editor-inner{position:relative}.gs-editor .gs-editor-hl{box-sizing:content-box;border:solid 2px var(--gs-accent,#2563eb);margin:-2px -1px}.gs-editor textarea{width:100%;padding:0 2px!important;position:absolute;font-size:12px;font-family:monospace,Arial;line-height:24px;letter-spacing:1px;top:0;left:0;border:none;outline:0;background-color:transparent;color:transparent;resize:none;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;overflow:hidden;cursor:default;white-space:pre;height:auto}.gs-editor.gs-editing{z-index:11;opacity:1}.gs-editor.gs-editing .gs-cell-label{pointer-events:none;font-family:inherit;font-weight:500;position:absolute;top:0;right:0;margin-top:-17px;margin-right:-2px;padding:1px 5px;border-top-left-radius:4px;border-top-right-radius:4px;font-size:10px;background-color:var(--gs-accent,#2563eb);color:#fff;z-index:1}.gs-formula-bar{width:100%;position:relative;display:flex;align-items:stretch;box-sizing:border-box;border-style:solid;border-color:var(--gs-border,#e3e6ea);border-width:var(--gs-fb-bt,1px) var(--gs-fb-br,1px) var(--gs-fb-bb,1px) var(--gs-fb-bl,1px);padding:3px 6px;gap:6px}.gs-formula-bar .gs-selecting-address{display:flex;align-items:center;justify-content:center;min-width:38px;padding:0 4px;color:var(--gs-muted-fg,#6b7280);font-size:12px;font-variant-numeric:tabular-nums;text-align:center}.gs-formula-bar[data-spill=true]{background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 6%,var(--gs-header-bg,#f4f5f7))}.gs-formula-bar[data-spill=true] .gs-selecting-address{color:var(--gs-accent,#2563eb);font-style:italic}.gs-formula-bar[data-spill=true] .gs-selecting-address::after{content:"\2196";margin-left:2px;font-style:normal;font-size:9px}.gs-formula-bar .gs-fx{display:flex;align-items:center;justify-content:center;align-self:center;width:26px;height:18px;flex-shrink:0;color:var(--gs-muted-fg,#6b7280);font-style:italic;font-family:inherit;font-weight:400;text-align:center;font-size:13px;letter-spacing:.3px;border-radius:4px;background-color:color-mix(in srgb,var(--gs-fg,#1f2328) 6%,transparent)}.gs-formula-bar .gs-editor-hl{z-index:0;overflow-y:auto;box-sizing:border-box;white-space:pre-wrap;word-break:break-all;text-align:left;line-height:24px}.gs-formula-bar textarea{position:relative;z-index:1;width:100%;vertical-align:bottom;color:transparent;border:none;background-color:transparent;padding:0 2px;box-sizing:border-box;text-align:left;outline:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;font-size:12px;font-family:monospace,Arial;height:24px;line-height:24px;min-height:24px;letter-spacing:1px;resize:vertical;caret-color:var(--gs-fg,#1f2328);white-space:pre-wrap;word-break:break-all}.gs-token-type-INVALID_REF{color:red}.gs-token-type-VALUE.gs-token-entity-type-boolean,.gs-token-type-VALUE.gs-token-entity-type-number{color:#39f}.gs-token-type-VALUE.gs-token-entity-type-string{color:#090}.gs-editor-options{position:fixed;z-index:1000;padding:4px;background:var(--gs-bg,#fff);box-shadow:0 4px 12px rgba(0,0,0,.15);border:1px solid rgba(0,0,0,.1);border-radius:6px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;overflow:visible}.gs-editor-option{position:relative;cursor:pointer;list-style:none;padding:6px 12px;font-size:13px;border-radius:4px;color:#333;margin-bottom:2px}.gs-editor-option-content{display:flex;justify-content:space-between;width:100%;align-items:center}.gs-editor-option-tab{font-size:10px;color:#aaa;margin-left:8px;padding:2px 4px;border:1px solid #ddd;border-radius:3px;background:#f9f9f9}.gs-editor-option:last-child{margin-bottom:0}.gs-editor-option:hover{background-color:#f5f5f5}.gs-editor-option-selected{background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);color:var(--gs-accent,#2563eb);font-weight:500}.gs-editor-option-selected:hover{background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 18%,transparent)}.gs-fn-guide1{position:absolute;top:-4px;left:calc(100% + 8px);background:#fff;border:1px solid rgba(0,0,0,.1);box-shadow:0 4px 16px rgba(0,0,0,.12);border-radius:6px;padding:16px;width:280px;z-index:1000;cursor:default;white-space:normal;color:#333}.gs-fn-guide1-tooltip{margin-bottom:8px;line-height:1.4;font-size:13px}.gs-fn-guide1-example{font-family:monospace;font-weight:600;font-size:13px;margin-bottom:8px;color:#1a1a1a;background:#f5f5f5;padding:6px 8px;border-radius:4px;border:1px solid #eee;display:flex;align-items:center;gap:6px;flex-wrap:wrap}.gs-fn-guide1-desc{font-size:13px;color:#555;margin-bottom:12px;line-height:1.4}.gs-fn-guide1-desc p{margin:0 0 6px 0}.gs-fn-guide1-desc p:last-child{margin-bottom:0}.gs-fn-guide1-args{border-top:1px solid #eee;padding-top:10px}.gs-fn-guide1-arg{margin-bottom:6px;line-height:1.4;font-size:12px}.gs-fn-guide1-arg-name{font-weight:600;color:var(--gs-accent,#2563eb)}.gs-fn-guide1-arg-opt{color:#888;font-size:11px}.gs-fn-guide1-arg-iter{font-weight:600;color:var(--gs-accent,#2563eb)}.gs-fn-guide1-arg-type{color:var(--gs-accent,#2563eb);padding:0 4px;background:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);border-radius:3px;font-size:11px;margin:0 4px}.gs-fn-guide1-arg-desc{color:#666}.gs-fn-guide-category{position:absolute;top:-11px;right:8px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;font-size:11px;font-weight:600;letter-spacing:.5px;text-transform:uppercase;padding:2px 7px;border-radius:4px;background:#e8eaf6;color:#3949ab;border:1px solid #c5cae9;white-space:nowrap}.gs-fn-guide-category.gs-fn-guide-category-math{background:#e3f2fd;color:#1565c0;border-color:#bbdefb}.gs-fn-guide-category.gs-fn-guide-category-statistics{background:#e8f5e9;color:#2e7d32;border-color:#c8e6c9}.gs-fn-guide-category.gs-fn-guide-category-text{background:#fff8e1;color:#f57f17;border-color:#ffecb3}.gs-fn-guide-category.gs-fn-guide-category-time{background:#fce4ec;color:#880e4f;border-color:#f8bbd0}.gs-fn-guide-category.gs-fn-guide-category-lookup{background:#f3e5f5;color:#6a1b9a;border-color:#e1bee7}.gs-fn-guide-category.gs-fn-guide-category-logical{background:#e0f2f1;color:#00695c;border-color:#b2dfdb}.gs-fn-guide-category.gs-fn-guide-category-information{background:#e0f7fa;color:#006064;border-color:#b2ebf2}.gs-fn-guide-category.gs-fn-guide-category-finance{background:#fff3e0;color:#e65100;border-color:#ffe0b2}.gs-fn-guide-category.gs-fn-guide-category-engineering{background:#efebe9;color:#4e342e;border-color:#d7ccc8}.gs-fn-guide-category.gs-fn-guide-category-ai{background:#e8eaf6;color:#3949ab;border-color:#c5cae9}.gs-fn-guide-category.gs-fn-guide-category-other{background:#f5f5f5;color:#616161;border-color:#e0e0e0}.gs-editor-portal{display:contents}.gs-editor-portal[data-mode=dark] .gs-editor-options,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-options,.gs-editor[data-mode=dark] .gs-editor-options,.gs-editor[data-mode=inherit-dark] .gs-editor-options{background:#252526;border-color:#454545;box-shadow:0 4px 12px rgba(0,0,0,.5)}.gs-editor-portal[data-mode=dark] .gs-editor-option,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option,.gs-editor[data-mode=dark] .gs-editor-option,.gs-editor[data-mode=inherit-dark] .gs-editor-option{color:#ccc}.gs-editor-portal[data-mode=dark] .gs-editor-option:hover,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option:hover,.gs-editor[data-mode=dark] .gs-editor-option:hover,.gs-editor[data-mode=inherit-dark] .gs-editor-option:hover{background-color:#333}.gs-editor-portal[data-mode=dark] .gs-editor-option-selected,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option-selected,.gs-editor[data-mode=dark] .gs-editor-option-selected,.gs-editor[data-mode=inherit-dark] .gs-editor-option-selected{background-color:#094771;color:#fff}.gs-editor-portal[data-mode=dark] .gs-editor-option-selected:hover,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option-selected:hover,.gs-editor[data-mode=dark] .gs-editor-option-selected:hover,.gs-editor[data-mode=inherit-dark] .gs-editor-option-selected:hover{background-color:#0d5a8f}.gs-editor-portal[data-mode=dark] .gs-editor-option-tab,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option-tab,.gs-editor[data-mode=dark] .gs-editor-option-tab,.gs-editor[data-mode=inherit-dark] .gs-editor-option-tab{color:#777;background:#333;border-color:#444}.gs-editor-portal[data-mode=dark] .gs-fn-guide1,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1,.gs-editor[data-mode=dark] .gs-fn-guide1,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1{background:#252526;border-color:#454545;color:#ccc}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-example,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-example,.gs-editor[data-mode=dark] .gs-fn-guide1-example,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-example{background:#1e1e1e;border-color:#333;color:#d4d4d4}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-desc,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-desc,.gs-editor[data-mode=dark] .gs-fn-guide1-desc,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-desc{color:#aaa}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-args,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-args,.gs-editor[data-mode=dark] .gs-fn-guide1-args,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-args{border-color:#333}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-iter,.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-name,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-iter,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-name,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-iter,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-name,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-iter,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-name{color:#4fc1ff}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-opt,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-opt,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-opt,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-opt{color:#777}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-type,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-type,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-type,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-type{background:#094771;color:#4fc1ff}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-desc,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-desc,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-desc,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-desc{color:#999}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category,.gs-editor[data-mode=dark] .gs-fn-guide-category,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category{background:#2a2d3e;color:#7986cb;border-color:#3d4166}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-math,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-math,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-math,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-math{background:#0d2137;color:#64b5f6;border-color:#1a3a5c}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-statistics,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-statistics,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-statistics,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-statistics{background:#0d2218;color:#66bb6a;border-color:#1a3d2a}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-text,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-text,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-text,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-text{background:#2e2200;color:#ffd54f;border-color:#4d3900}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-time,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-time,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-time,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-time{background:#2d0d1e;color:#f48fb1;border-color:#4d1a33}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-lookup,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-lookup,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-lookup,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-lookup{background:#260d33;color:#ce93d8;border-color:#3d1a54}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-logical,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-logical,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-logical,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-logical{background:#0d2421;color:#4db6ac;border-color:#1a3d39}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-information,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-information,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-information,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-information{background:#0d2426;color:#4dd0e1;border-color:#1a3d40}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-finance,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-finance,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-finance,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-finance{background:#2e1500;color:#ffb74d;border-color:#4d2800}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-engineering,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-engineering,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-engineering,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-engineering{background:#1e1714;color:#bcaaa4;border-color:#332c28}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-ai,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-ai,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-ai,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-ai{background:#10142e;color:#7986cb;border-color:#232a52}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-other,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-other,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-other,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-other{background:#1e1e1e;color:#9e9e9e;border-color:#333}.gs-editor-portal[data-mode=dark] .gs-fn-guide2,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2,.gs-editor[data-mode=dark] .gs-fn-guide2,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2{background:#252526;border-color:#454545;box-shadow:0 4px 12px rgba(0,0,0,.5);color:#ccc}.gs-editor-portal[data-mode=dark] .gs-fn-guide2-name,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2-name,.gs-editor[data-mode=dark] .gs-fn-guide2-name,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2-name{color:#dfdbdb;background:#333;border-color:#444}.gs-editor-portal[data-mode=dark] .gs-fn-guide2 .gs-active-arg,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2 .gs-active-arg,.gs-editor[data-mode=dark] .gs-fn-guide2 .gs-active-arg,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2 .gs-active-arg{color:#fff;background-color:#094771}.gs-editor-portal[data-mode=dark] .gs-fn-guide2-arg-type,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2-arg-type,.gs-editor[data-mode=dark] .gs-fn-guide2-arg-type,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2-arg-type{background:#094771;color:#4fc1ff}.gs-editor-portal[data-mode=dark] .gs-fn-guide2-desc,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2-desc,.gs-editor[data-mode=dark] .gs-fn-guide2-desc,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2-desc{color:#aaa;border-top-color:#333}.gs-fn-guide2{position:fixed;left:0;background:#fff;border:1px solid rgba(0,0,0,.1);box-shadow:0 4px 16px rgba(0,0,0,.12);border-radius:6px;padding:12px 16px;width:280px;z-index:1000;cursor:default;white-space:normal;color:#333;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;transition:opacity .1s ease-in-out}.gs-fn-guide2.gs-fn-guide2-hidden{opacity:0!important;pointer-events:none!important}.gs-fn-guide2-name{font-family:monospace;font-weight:700;font-size:13px;color:#1a1a1a;background:#f5f5f5;padding:6px 8px;border-radius:4px;border:1px solid #eee;display:flex;align-items:center;gap:6px;flex-wrap:wrap;width:100%;box-sizing:border-box;margin-bottom:8px}.gs-fn-guide2-args-inline{font-size:13px;font-family:monospace;line-height:1.5;margin-bottom:8px;color:#666}.gs-fn-guide2-args-inline span{transition:all .2s ease-in-out}.gs-fn-guide2 .gs-active-arg{font-weight:700;color:var(--gs-accent,#2563eb);background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);padding:2px 4px;margin:0 -4px;border-radius:4px}.gs-fn-guide2-arg-type{color:var(--gs-accent,#2563eb);padding:0 4px;background:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);border-radius:3px;font-size:11px;margin:0 4px}.gs-fn-guide2-desc{font-size:12px;color:#555;line-height:1.4;border-top:1px solid #eee;padding-top:8px;margin-top:4px}.gs-fn-guide2-desc p{margin:0}.gs-fn-guide2-desc-more{font-style:italic;color:#888;margin-top:4px!important;font-size:11px}.gs-adjuster{padding:0}.gs-table{margin:0}.gs-tabular{overflow:auto;overflow-anchor:none;display:flex;box-sizing:border-box;position:relative}.gs-root1[data-matrix-align=both] .gs-tabular,.gs-root1[data-matrix-align=horizontal] .gs-tabular{justify-content:safe center}.gs-root1[data-matrix-align=both] .gs-tabular,.gs-root1[data-matrix-align=vertical] .gs-tabular{align-items:safe center}.gs-tabular-inner{flex:0 0 auto;position:relative;overflow:hidden;overflow:clip;box-sizing:border-box;border-right:solid var(--gs-mx-br,1px) var(--gs-border,#e3e6ea);border-bottom:solid var(--gs-mx-bb,1px) var(--gs-border,#e3e6ea)}.gs-tabular-inner>table{table-layout:fixed;border-collapse:collapse;border-spacing:0}.gs-ghost-cell{padding:0;box-sizing:border-box;border:dashed 1px var(--gs-border,#e3e6ea);background-color:var(--gs-surface,#fff);opacity:.5;cursor:crosshair}.gs-ghost-th{opacity:.5}.gs-ghost-th-top{top:0}.gs-ghost-th-left{left:0}.gs-main[data-overflow-x=true] .gs-tabular-inner{border-right-width:0}.gs-main[data-overflow-y=true] .gs-tabular-inner{border-bottom-width:0}.gs-main::after{content:'';position:absolute;inset:0;pointer-events:none;z-index:3;border:0 solid var(--gs-border,#e3e6ea)}.gs-main[data-overflow-x=true]::after{border-right-width:var(--gs-mx-br,1px)}.gs-main[data-overflow-y=true]::after{border-bottom-width:var(--gs-mx-bb,1px)}.gs-th{z-index:2;padding:0;position:sticky;font-size:13px;font-weight:400;box-sizing:border-box;vertical-align:top}.gs-th .gs-resizer{position:absolute;border-color:transparent;box-sizing:border-box;z-index:2}.gs-th .gs-resizer:hover{background-color:var(--gs-accent,#2563eb)}.gs-th .gs-resizer.gs-protected{display:none}.gs-th-inner{height:100%;box-sizing:border-box;vertical-align:middle;overflow:hidden;display:flex;align-items:center;justify-content:center}.gs-th-inner-wrap{height:100%;box-sizing:border-box;background-color:transparent}.gs-th-top{top:0;overflow:hidden}.gs-th-top .gs-resizer{top:0;right:0;width:3px;cursor:e-resize}.gs-th-top .gs-resizer.gs-dragging{border-right-style:dotted;height:1000000px!important;cursor:e-resize}.gs-th-left{left:0;overflow:hidden;min-width:30px;border-top:solid 1px var(--gs-border,#e3e6ea)}.gs-th-left .gs-resizer{left:0;bottom:0;height:3px;cursor:n-resize}.gs-th-left .gs-resizer.gs-dragging{border-bottom-style:dotted;width:1000000px!important;cursor:n-resize}.gs-th-top.gs-th-left{top:0;left:0;z-index:3;border:none!important}.gs-th-left.gs-filter-fixed .gs-th-inner::before{content:'‹\00a0'}.gs-th-left.gs-sort-fixed .gs-th-inner::after{content:'\00a0›'}.gs-col-addr{position:absolute;top:2px;right:4px;font-size:9px;opacity:.5;line-height:1;letter-spacing:.3px;pointer-events:none}.gs-search-bar{width:100%;display:flex;align-items:center;padding:3px 0;border-top:solid 1px rgba(128,128,128,.3);border-left:solid 1px rgba(128,128,128,.3);border-right:solid 1px rgba(128,128,128,.3);border-bottom:solid 1px rgba(128,128,128,.3);box-sizing:border-box;background-color:rgba(200,50,0,.2)}.gs-search-bar.gs-search-found{background-color:rgba(0,200,100,.2)}.gs-search-bar .gs-search-bar-inner{border-left:solid 1px rgba(128,128,128,.5)}.gs-search-bar .gs-search-bar-icon{border-left:solid 1px rgba(128,128,128,.3);display:flex;align-items:center;justify-content:center;width:30px;flex-shrink:0}.gs-search-bar .gs-search-input-wrapper{flex-grow:1;position:relative;display:flex;align-items:center;height:100%}.gs-search-bar .gs-search-input-ghost{position:absolute;left:2px;right:2px;top:0;bottom:0;pointer-events:none;font-size:12px;font-family:monospace,Arial;line-height:24px;letter-spacing:1px;white-space:pre-wrap;word-break:break-all;color:transparent;overflow:hidden}.gs-search-bar .gs-search-input-ghost .gs-search-ghost-hint{color:#aaa}.gs-search-bar textarea{background-color:transparent;border:none;padding:0 2px;box-sizing:border-box;outline:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;font-size:12px;font-family:monospace,Arial;height:24px;line-height:24px;min-height:24px;letter-spacing:1px;caret-color:rgba(128,128,128);white-space:pre-wrap;word-break:break-all;flex-grow:1;width:100%;resize:none}.gs-search-progress{color:#999;font-size:13px;width:60px;flex-shrink:0;white-space:nowrap;text-align:center}.gs-search-close{cursor:pointer;display:flex;align-items:center;justify-content:center;width:24px;flex-shrink:0}.gs-search-buttons{display:flex;align-items:center;white-space:nowrap;flex-shrink:0}.gs-search-button{display:inline-flex;cursor:pointer;margin:0 2px}.gs-search-button span{display:inline-block;font-size:11px;padding:3px 5px;background-color:rgba(128,128,128,.1);border:1px solid rgba(128,128,128,.3);border-radius:3px;transition:all .15s ease;line-height:1}.gs-search-button span:hover{background-color:rgba(128,128,128,.2)}.gs-search-button span.gs-search-button-on{color:var(--gs-accent,#2563eb);background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 22%,transparent);border-color:var(--gs-accent,#2563eb)}.gs-search-range span{white-space:nowrap;font-family:monospace}@keyframes spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}.gs-loading-overlay{position:absolute;top:0;left:0;right:0;bottom:0;background:color-mix(in srgb,var(--gs-surface,#fff) 70%,transparent);display:flex;align-items:center;justify-content:center;z-index:100;pointer-events:all}.gs-loading-spinner{width:32px;height:32px;border:3px solid color-mix(in srgb,var(--gs-fg,#1f2328) 12%,transparent);border-top-color:var(--gs-accent,#2563eb);border-radius:50%;animation:spin .8s linear infinite}.gs-progress-overlay{position:absolute;top:0;left:0;right:0;bottom:0;z-index:100;pointer-events:all;display:flex;align-items:center;justify-content:center}.gs-progress-box{min-width:240px;padding:16px 18px;border-radius:8px;background:var(--gs-editor-surface,#fff);border:1px solid var(--gs-border,#e3e6ea);box-shadow:0 6px 24px rgba(0,0,0,.28);display:flex;flex-direction:column;gap:10px}.gs-progress-head{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--gs-fg,#1f2328)}.gs-progress-head .gs-loading-spinner{width:15px;height:15px;border-width:2px}.gs-progress-track{height:6px;border-radius:3px;overflow:hidden;background:color-mix(in srgb,var(--gs-fg,#1f2328) 12%,transparent)}.gs-progress-fill{height:100%;border-radius:3px;background:var(--gs-accent,#2563eb);transition:width .1s linear}@keyframes gs-pending-slide{0%{left:-40%}100%{left:100%}}@keyframes gs-pending-pulse{0%{left:0;width:0}50%{left:0;width:100%}100%{left:100%;width:0}}@keyframes gs-flash{0%{opacity:0}20%{opacity:1}100%{opacity:0}}.gs-flash-overlay{position:absolute;inset:0;pointer-events:none;z-index:9999;background:color-mix(in srgb,var(--gs-accent,#2563eb) 15%,transparent);opacity:0}.gs-flash-overlay--active{animation:gs-flash .6s ease-out forwards} \ No newline at end of file diff --git a/packages/web/src/styles/tabular.less b/packages/web/src/styles/tabular.less index 7b0dd0b6..f5685e91 100644 --- a/packages/web/src/styles/tabular.less +++ b/packages/web/src/styles/tabular.less @@ -41,13 +41,33 @@ box-sizing: border-box; border-right: solid var(--gs-mx-br, 1px) var(--gs-border, #e3e6ea); border-bottom: solid var(--gs-mx-bb, 1px) var(--gs-border, #e3e6ea); - &>table { + & > table { table-layout: fixed; border-collapse: collapse; border-spacing: 0; } } +// autoExpand ghost rows/columns: the not-yet-existing cells past the last row/column, rendered +// only while an autofill is dragged on an auto-expanding sheet so the drag can reach them. +.gs-ghost-cell { + padding: 0; + box-sizing: border-box; + border: dashed 1px var(--gs-border, #e3e6ea); + background-color: var(--gs-surface, #ffffff); + opacity: 0.5; + cursor: crosshair; +} +.gs-ghost-th { + opacity: 0.5; +} +.gs-ghost-th-top { + top: 0; +} +.gs-ghost-th-left { + left: 0; +} + // When an axis overflows, the hugging inner border would scroll out of view, so move that // side to a viewport overlay on .gs-main (which does not scroll). The overlay sits on top // of the content so it covers the edge line instead of doubling it. .gs-main carries @@ -176,4 +196,4 @@ line-height: 1; letter-spacing: 0.3px; pointer-events: none; -} \ No newline at end of file +} From bbb207611190a3e67b2e56d6e67bf6e303050185 Mon Sep 17 00:00:00 2001 From: righ Date: Sun, 4 Oct 2026 05:00:27 +0900 Subject: [PATCH 2/6] fix(react-core): export AutoExpandType / HistoryBatchType from the entry Co-Authored-By: Claude Opus 5.5 --- packages/react-core/src/index.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/react-core/src/index.ts b/packages/react-core/src/index.ts index 108a1dec..dc820bbb 100644 --- a/packages/react-core/src/index.ts +++ b/packages/react-core/src/index.ts @@ -89,6 +89,8 @@ export type { HeadersType, HistoryType, HistorySortRowsType, + HistoryBatchType, + AutoExpandType, PointType, AreaType, ZoneType, From eb7a302559ba4550f21276085309430c51890538 Mon Sep 17 00:00:00 2001 From: righ Date: Sun, 4 Oct 2026 18:11:22 +0900 Subject: [PATCH 3/6] chore(storybook): make the AutoExpand story resizable Co-Authored-By: Claude Opus 5.5 --- packages/storybook/stories/restriction/autoExpand.stories.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/storybook/stories/restriction/autoExpand.stories.tsx b/packages/storybook/stories/restriction/autoExpand.stories.tsx index b14233ae..b05f49c0 100644 --- a/packages/storybook/stories/restriction/autoExpand.stories.tsx +++ b/packages/storybook/stories/restriction/autoExpand.stories.tsx @@ -15,6 +15,7 @@ const DESCRIPTION = [ '2. While dragging the autofill handle, ghost rows/columns appear past the edge so the drag can reach cells that do not exist yet.', '3. Growth is capped by `limits.maxRows` / `limits.maxCols` (here 12 rows × 8 columns).', '4. The added rows/columns and the write undo together in a single step.', + '5. The sheet is resizable (`sheetResize: both`) — drag its bottom-right corner to see the grown rows/columns.', ].join('\n\n'); const MODES: AutoExpandType[] = ['none', 'vertical', 'horizontal', 'both']; @@ -32,7 +33,7 @@ const AutoExpandComponent: React.FC = () => { ))}
Date: Mon, 5 Oct 2026 02:42:21 +0900 Subject: [PATCH 4/6] chore(storybook): center the AutoExpand story's grid in its box Co-Authored-By: Claude Opus 5.5 --- .../storybook/stories/restriction/autoExpand.stories.tsx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/storybook/stories/restriction/autoExpand.stories.tsx b/packages/storybook/stories/restriction/autoExpand.stories.tsx index b05f49c0..41737de6 100644 --- a/packages/storybook/stories/restriction/autoExpand.stories.tsx +++ b/packages/storybook/stories/restriction/autoExpand.stories.tsx @@ -15,7 +15,7 @@ const DESCRIPTION = [ '2. While dragging the autofill handle, ghost rows/columns appear past the edge so the drag can reach cells that do not exist yet.', '3. Growth is capped by `limits.maxRows` / `limits.maxCols` (here 12 rows × 8 columns).', '4. The added rows/columns and the write undo together in a single step.', - '5. The sheet is resizable (`sheetResize: both`) — drag its bottom-right corner to see the grown rows/columns.', + '5. The sheet is resizable (`sheetResize: both`) — drag its bottom-right corner to see the grown rows/columns; `matrixAlignment: both` keeps the grid centered.', ].join('\n\n'); const MODES: AutoExpandType[] = ['none', 'vertical', 'horizontal', 'both']; @@ -33,7 +33,12 @@ const AutoExpandComponent: React.FC = () => { ))} Date: Mon, 5 Oct 2026 03:40:25 +0900 Subject: [PATCH 5/6] feat(react-core): draw autofill ghost rows/cols outside the sheet MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The autoExpand ghost area is now drawn outside the grid — portaled to , positioned fixed right past the last row/column (only once that edge is scrolled into view) — instead of as extra table rows inside the scroll area. Cells in the fill target are highlighted; StoreObserver doesn't edge-scroll while the pointer is over the ghost layer. Reverts the in-table ghost rendering and the virtualize() "scrolled past the content" tweaks it needed. Co-Authored-By: Claude Opus 5.5 --- e2e/auto-expand.spec.ts | 19 +- .../src/components/AutofillGhost.tsx | 219 ++++++++++++++++++ .../src/components/ScrollHandle.tsx | 29 +-- .../src/components/StoreObserver.tsx | 12 +- .../react-core/src/components/Tabular.tsx | 99 +------- packages/web/src/lib/virtualization.ts | 10 +- packages/web/src/styles/minified.ts | 4 +- packages/web/src/styles/root.min.css | 2 +- packages/web/src/styles/tabular.less | 51 ++-- 9 files changed, 283 insertions(+), 162 deletions(-) create mode 100644 packages/react-core/src/components/AutofillGhost.tsx diff --git a/e2e/auto-expand.spec.ts b/e2e/auto-expand.spec.ts index 26473fd6..70438969 100644 --- a/e2e/auto-expand.spec.ts +++ b/e2e/auto-expand.spec.ts @@ -72,18 +72,19 @@ test('autofill dragged past the last row fills the ghost rows', async ({ page }) await page.mouse.move(hb!.x + hb!.width / 2, hb!.y + hb!.height / 2); await page.mouse.down(); await page.mouse.move(hb!.x + hb!.width / 2, tb!.y + tb!.height - 4, { steps: 5 }); - // Ghost rows appear past the last row while dragging (once it is scrolled into view). - await expect(page.locator('.gs-ghost-row').first()).toBeAttached(); - // Past the bottom edge: the grid auto-scrolls into the ghost area. - await page.mouse.move(hb!.x + hb!.width / 2, tb!.y + tb!.height + 20, { steps: 3 }); - await page.waitForTimeout(800); + // Ghost rows are drawn outside the grid, right below its last row, while dragging. + const ghost = page.locator(".gs-ghost-cell[data-y='8'][data-x='1']"); + await expect(ghost).toBeVisible(); + const gb = await ghost.boundingBox(); + expect(gb!.y).toBeGreaterThanOrEqual(tb!.y + tb!.height - 2); // outside the sheet box + // Drag down onto the 3rd ghost row (row 8). + await page.mouse.move(gb!.x + gb!.width / 2, gb!.y + gb!.height / 2, { steps: 4 }); await page.mouse.up(); await expect(page.locator('.gs-ghost-cell')).toHaveCount(0); - // Rows were appended (5 → more) and the series continued into them. - expect(await text(page, 'A6')).toBe('6'); - // Capped at maxRows (12). - await expect(page.locator("[data-address='A13']")).toHaveCount(0); + // Rows 6..8 were appended and the series continued into them. + expect(await text(page, 'A8')).toBe('8'); + await expect(page.locator("[data-address='A9']")).toHaveCount(0); await ctrl(page, 'z'); await expect(page.locator("[data-address='A6']")).toHaveCount(0); diff --git a/packages/react-core/src/components/AutofillGhost.tsx b/packages/react-core/src/components/AutofillGhost.tsx new file mode 100644 index 00000000..951c825f --- /dev/null +++ b/packages/react-core/src/components/AutofillGhost.tsx @@ -0,0 +1,219 @@ +import { useCallback, useContext, useEffect, useState } from 'react'; +import type { CSSProperties, FC } from 'react'; +import { createPortal } from 'react-dom'; + +import { Context } from '../store'; +import { setAutofillDraggingTo } from '../store/actions'; +import { useBrowser } from '../lib/hooks'; +import { Autofill, among, getGhostCellSize, x2c } from '@gridsheet/web'; +import type { Sheet } from '@gridsheet/web'; + +// Ghost rows/cols kept beyond the drag target, so there is always room to drag further. +const GHOST_ROWS = 5; +const GHOST_COLS = 2; + +// Theme tokens the ghost cells use. The layer is portaled to (outside .gs-root1, whose +// overflow would clip anything drawn past the grid), so copy the resolved values over. +const THEME_VARS = ['--gs-border', '--gs-surface', '--gs-header-bg', '--gs-header-fg', '--gs-accent', '--gs-fg']; + +/** + * How many ghost rows/cols to show past the sheet's edge while an autofill is dragged on an + * auto-expanding sheet — enough to reach the current drag target plus some slack, capped by + * the max limits. Zero when the sheet can't grow that way. + */ +const getGhostCount = (sheet: Sheet, draggingTo: { y: number; x: number }) => { + const mode = sheet.autoExpand; + const room = (limit: number, current: number) => (limit === -1 ? Infinity : Math.max(0, limit - current)); + const rows = + mode === 'vertical' || mode === 'both' + ? Math.min(room(sheet.maxNumRows, sheet.numRows), Math.max(0, draggingTo.y - sheet.numRows) + GHOST_ROWS) + : 0; + const cols = + mode === 'horizontal' || mode === 'both' + ? Math.min(room(sheet.maxNumCols, sheet.numCols), Math.max(0, draggingTo.x - sheet.numCols) + GHOST_COLS) + : 0; + return { rows, cols }; +}; + +type Band = { index: number; start: number; size: number }; + +// The rendered header cells give each visible row/column's on-screen position, which already +// accounts for scrolling, the scroll-height remap and a centered matrix. +const readBands = (tabular: HTMLElement, selector: string, key: 'x' | 'y', horizontal: boolean): Band[] => + Array.from(tabular.querySelectorAll(selector)) + .filter((th) => th.dataset[key] != null) + .map((th) => { + const r = th.getBoundingClientRect(); + return { + index: Number(th.dataset[key]), + start: horizontal ? r.left : r.top, + size: horizontal ? r.width : r.height, + }; + }); + +/** + * The autoExpand ghost area: the not-yet-existing rows (below) / columns (right) drawn OUTSIDE + * the grid, right past its last row/column, while an autofill is dragged on an auto-expanding + * sheet. Dragging onto a ghost cell targets it; releasing grows the sheet (see Autofill). + * Shown only once the grid is scrolled to that edge, so the ghost always continues the last row/col. + */ +export const AutofillGhost: FC = () => { + const { store, dispatch } = useContext(Context); + const { sheetReactive, tabularRef, rootRef, autofillDraggingTo, mode } = store; + const sheet = sheetReactive.current; + const { document: doc } = useBrowser(); + const [, setTick] = useState(0); + const active = !!sheet && !!autofillDraggingTo && sheet.autoExpand !== 'none'; + + // Positions are read from the DOM, so re-render on anything that moves the grid. + useEffect(() => { + if (!active) { + return; + } + const bump = () => setTick((t) => t + 1); + const el = tabularRef.current; + el?.addEventListener('scroll', bump); + window.addEventListener('resize', bump); + window.addEventListener('scroll', bump, true); + return () => { + el?.removeEventListener('scroll', bump); + window.removeEventListener('resize', bump); + window.removeEventListener('scroll', bump, true); + }; + }, [active, tabularRef]); + + const handleEnter = useCallback( + (e: React.MouseEvent) => { + const y = Number(e.currentTarget.dataset.y); + const x = Number(e.currentTarget.dataset.x); + if (autofillDraggingTo && (y !== autofillDraggingTo.y || x !== autofillDraggingTo.x)) { + dispatch(setAutofillDraggingTo({ y, x })); + } + }, + [autofillDraggingTo], + ); + + const tabular = tabularRef.current; + const inner = tabular?.querySelector(':scope > .gs-tabular-inner'); + if (!active || !doc || !tabular || !inner || !sheet || !autofillDraggingTo) { + return null; + } + + const count = getGhostCount(sheet, autofillDraggingTo); + const ghost = getGhostCellSize(sheet); + const tab = tabular.getBoundingClientRect(); + const grid = inner.getBoundingClientRect(); + // The grid's last row/col is on screen only when scrolled to that edge. + const atBottom = tabular.scrollTop + tabular.clientHeight >= tabular.scrollHeight - 1; + const atRight = tabular.scrollLeft + tabular.clientWidth >= tabular.scrollWidth - 1; + const showRows = count.rows > 0 && atBottom; + const showCols = count.cols > 0 && atRight; + if (!showRows && !showCols) { + return null; + } + + const fillArea = new Autofill(store, autofillDraggingTo).wholeArea; + const viewLeft = tab.left + tabular.clientLeft; + const viewTop = tab.top + tabular.clientTop; + const viewRight = viewLeft + tabular.clientWidth; + const viewBottom = viewTop + tabular.clientHeight; + const gridRight = Math.min(grid.right, viewRight); + const gridBottom = Math.min(grid.bottom, viewBottom); + const headerW = sheet.headerWidth; + const headerH = sheet.headerHeight; + + const cols = readBands(tabular, '.gs-th-top', 'x', true); + const rows = readBands(tabular, '.gs-th-left', 'y', false); + const ghostCols: Band[] = showCols + ? Array.from({ length: count.cols }, (_, i) => ({ + index: sheet.numCols + 1 + i, + start: gridRight + i * ghost.width, + size: ghost.width, + })) + : []; + + const cell = (y: number, x: number, style: CSSProperties) => ( +
+ ); + + const vars: Record = {}; + if (rootRef.current) { + const cs = getComputedStyle(rootRef.current); + THEME_VARS.forEach((v) => (vars[v] = cs.getPropertyValue(v))); + vars.fontFamily = cs.fontFamily; + } + + return createPortal( +
+ {showRows && ( + // Rows below the grid: one per ghost row, cells under each visible (and ghost) column. +
+ {Array.from({ length: count.rows }, (_, i) => { + const y = sheet.numRows + 1 + i; + const top = i * ghost.height; + return [ + ...[...cols, ...ghostCols].map((c) => + cell(y, c.index, { left: c.start - viewLeft, top, width: c.size, height: ghost.height }), + ), +
+ {y} +
, + ]; + })} +
+ )} + {showCols && ( + // Columns right of the grid: a header per ghost column, cells beside each visible row. +
+ {ghostCols.map((c, i) => [ + ...rows + .filter((r) => r.start + r.size > viewTop + headerH) + .map((r) => + cell(r.index, c.index, { + left: i * ghost.width, + top: r.start - viewTop, + width: c.size, + height: r.size, + }), + ), +
+ {x2c(c.index)} +
, + ])} +
+ )} +
, + doc.body, + ); +}; diff --git a/packages/react-core/src/components/ScrollHandle.tsx b/packages/react-core/src/components/ScrollHandle.tsx index d875726c..c07a42ce 100644 --- a/packages/react-core/src/components/ScrollHandle.tsx +++ b/packages/react-core/src/components/ScrollHandle.tsx @@ -72,29 +72,6 @@ export function ScrollHandle({ style, horizontal = 0, vertical = 0, className = [sheet, horizontal, vertical, selectingZone], ); - // The autoExpand ghost cell just inside the scrolling edge, if any. getDestEdge finds the edge - // from header cells, which ghost rows/cols don't have. This strip sits on top of the grid, - // so look through it with elementsFromPoint. - const getGhostEdgePoint = useCallback( - (e: React.MouseEvent) => { - const el = tabularRef.current; - if (!el) { - return null; - } - const r = el.getBoundingClientRect(); - const px = horizontal > 0 ? r.right - 2 : Math.min(Math.max(e.clientX, r.left + 1), r.right - 2); - const py = vertical > 0 ? r.bottom - 2 : Math.min(Math.max(e.clientY, r.top + 1), r.bottom - 2); - const ghost = document - .elementsFromPoint(px, py) - .find((node) => (node as HTMLElement).classList?.contains('gs-ghost-cell')) as HTMLElement | undefined; - if (!ghost) { - return null; - } - return { y: Number(ghost.dataset.y), x: Number(ghost.dataset.x) }; - }, - [horizontal, vertical], - ); - const scrollStep = useCallback( (e: React.MouseEvent) => { if (!isScrolling || tabularRef.current === null || !sheet) { @@ -128,10 +105,7 @@ export function ScrollHandle({ style, horizontal = 0, vertical = 0, className = const { x, y } = getDestEdge(e); if (live.autofillDraggingTo) { const { y: curY, x: curX } = live.autofillDraggingTo; - // On an auto-expanding sheet the drag scrolls on into ghost rows/cols past the last - // row/col, which have no header cells for getDestEdge to find — target that cell instead. - const ghostPoint = getGhostEdgePoint(e); - dispatch(setAutofillDraggingTo(ghostPoint ?? { y: y === -1 ? curY : y, x: x === -1 ? curX : x })); + dispatch(setAutofillDraggingTo({ y: y === -1 ? curY : y, x: x === -1 ? curX : x })); } else { if (editingAnywhere) { const newArea = zoneToArea({ ...selectingZone, endY: y, endX: x }); @@ -155,7 +129,6 @@ export function ScrollHandle({ style, horizontal = 0, vertical = 0, className = selectingZone, xSheetFocused, getDestEdge, - getGhostEdgePoint, ], ); diff --git a/packages/react-core/src/components/StoreObserver.tsx b/packages/react-core/src/components/StoreObserver.tsx index 5d9ee39e..1c9359d8 100644 --- a/packages/react-core/src/components/StoreObserver.tsx +++ b/packages/react-core/src/components/StoreObserver.tsx @@ -90,6 +90,15 @@ export const StoreObserver: FC = ({ running = false; return; } + // Over the autoExpand ghost cells drawn outside the grid: the pointer is past the edge, but + // the ghost cell itself is the target (its own mouseenter sets it) — don't edge-scroll. + if ( + s.autofillDraggingTo && + (document.elementFromPoint(cx, cy) as HTMLElement | null)?.closest('.gs-ghost-layer') + ) { + raf = requestAnimationFrame(tick); + return; + } const r = el.getBoundingClientRect(); const dy = cy > r.bottom - EDGE ? SPEED : cy < r.top + EDGE ? -SPEED : 0; const dx = cx > r.right - EDGE ? SPEED : cx < r.left + EDGE ? -SPEED : 0; @@ -98,9 +107,8 @@ export const StoreObserver: FC = ({ el.scrollLeft += dx; const px = Math.min(Math.max(cx, r.left + 1), r.right - 1); const py = Math.min(Math.max(cy, r.top + 1), r.bottom - 1); - // Ghost cells (autoExpand) past the last row/col carry data-y/x like real cells. const cell = (document.elementFromPoint(px, py) as HTMLElement | null)?.closest( - '.gs-cell, .gs-ghost-cell', + '.gs-cell', ) as HTMLElement | null; if (cell) { const y = Number(cell.dataset.y); diff --git a/packages/react-core/src/components/Tabular.tsx b/packages/react-core/src/components/Tabular.tsx index 5f8b2509..8a744a3c 100644 --- a/packages/react-core/src/components/Tabular.tsx +++ b/packages/react-core/src/components/Tabular.tsx @@ -4,45 +4,17 @@ import { Cell, type MergeRender } from './Cell'; import { HeaderCellTop } from './HeaderCellTop'; import { HeaderCellLeft } from './HeaderCellLeft'; import { CellStateOverlay } from './CellStateOverlay'; +import { AutofillGhost } from './AutofillGhost'; import { Context } from '../store'; -import { choose, select, setAutofillDraggingTo, setContextMenuPosition } from '../store/actions'; +import { choose, select, setContextMenuPosition } from '../store/actions'; import type { RefPaletteType, Virtualization } from '../types'; -import { virtualize, physicalScrollHeight, getGhostCellSize, SCROLL_CAP, range, x2c } from '@gridsheet/web'; +import { virtualize, physicalScrollHeight } from '@gridsheet/web'; import { p2a, stripAddressAbsolute } from '@gridsheet/web'; import { Lexer, stripSheetName } from '@gridsheet/web'; import { ScrollHandle } from './ScrollHandle'; import { preventSafariBounce } from '@gridsheet/web'; -import type { Sheet } from '@gridsheet/web'; - -// Ghost rows/cols kept beyond the drag target, so there is always room to drag (and -// auto-scroll) further past the sheet's edge. -const GHOST_ROWS = 5; -const GHOST_COLS = 2; - -/** - * How many ghost rows/cols to show past the sheet's edge while an autofill is dragged on an - * auto-expanding sheet — enough to reach the current drag target plus some slack, capped by - * the max limits. Zero when the sheet can't grow that way. - */ -const getGhostCount = (sheet: Sheet, draggingTo: { y: number; x: number } | null) => { - const mode = sheet.autoExpand; - if (!draggingTo || mode === 'none') { - return { rows: 0, cols: 0 }; - } - const room = (limit: number, current: number) => (limit === -1 ? Infinity : Math.max(0, limit - current)); - // A capped (remapped) scroll height can't be extended linearly, so very tall sheets get no row ghosts. - const rows = - (mode === 'vertical' || mode === 'both') && sheet.totalHeight <= SCROLL_CAP - ? Math.min(room(sheet.maxNumRows, sheet.numRows), Math.max(0, draggingTo.y - sheet.numRows) + GHOST_ROWS) - : 0; - const cols = - mode === 'horizontal' || mode === 'both' - ? Math.min(room(sheet.maxNumCols, sheet.numCols), Math.max(0, draggingTo.x - sheet.numCols) + GHOST_COLS) - : 0; - return { rows, cols }; -}; export const Tabular = () => { const [palette, setPalette] = useState({}); @@ -61,7 +33,6 @@ export const Tabular = () => { leftHeaderSelecting, topHeaderSelecting, contextMenu, - autofillDraggingTo, } = store; const sheet = sheetReactive.current; @@ -97,21 +68,6 @@ export const Tabular = () => { e.stopPropagation(); }, []); - // Dragging an autofill onto a ghost cell targets that (not yet existing) cell. - const handleGhostMouseEnter = useCallback( - (e: React.MouseEvent) => { - if (!autofillDraggingTo) { - return; - } - const y = Number(e.currentTarget.dataset.y); - const x = Number(e.currentTarget.dataset.x); - if (y !== autofillDraggingTo.y || x !== autofillDraggingTo.x) { - dispatch(setAutofillDraggingTo({ y, x })); - } - }, - [autofillDraggingTo], - ); - const handleScroll = useCallback( (e: React.UIEvent) => { if (sheet) { @@ -264,22 +220,6 @@ export const Tabular = () => { return null; } - const ghostCount = getGhostCount(sheet, autofillDraggingTo); - const ghostSize = getGhostCellSize(sheet); - const ghostHeight = ghostCount.rows * ghostSize.height; - const ghostWidth = ghostCount.cols * ghostSize.width; - const scrollHeight = physicalScrollHeight(sheet); - const ghostXs = ghostCount.cols > 0 ? range(sheet.numCols + 1, sheet.numCols + ghostCount.cols) : []; - // Ghost rows follow the last row, so they only render once the rendered window reaches the - // bottom (offset-based, so trailing filtered — zero-height — rows don't hide them). - const lastRendered = virtualized?.ys?.[virtualized.ys.length - 1]; - const lastRowRendered = lastRendered != null && sheet.getOffsetTop(lastRendered + 1) >= sheet.totalHeight; - const ghostYs = - ghostCount.rows > 0 && lastRowRendered ? range(sheet.numRows + 1, sheet.numRows + ghostCount.rows) : []; - const ghostCell = (y: number, x: number) => ( - - ); - return ( <>
{
@@ -357,15 +296,6 @@ export const Tabular = () => { className="gs-adjuster gs-adjuster-horizontal gs-adjuster-horizontal-right" style={{ width: virtualized?.adjuster?.right }} > - {ghostXs.map((x) => ( - -
{x2c(x)}
- - ))} @@ -378,9 +308,6 @@ export const Tabular = () => { {virtualized?.xs?.map((x) => )} - {ghostXs.map((x) => ( - - ))} @@ -392,28 +319,14 @@ export const Tabular = () => { {virtualized?.xs?.map((x) => )} - {ghostXs.map((x) => ghostCell(y, x))} ); })} - {/* autoExpand ghost rows: shown past the last row only while an autofill is dragged. */} - {ghostYs.map((y) => ( - - -
- {y} -
- - - {virtualized?.xs?.map((x) => ghostCell(y, x))} - - {ghostXs.map((x) => ghostCell(y, x))} - - ))}
+ ); }; diff --git a/packages/web/src/lib/virtualization.ts b/packages/web/src/lib/virtualization.ts index 619a1771..bcbed6a9 100644 --- a/packages/web/src/lib/virtualization.ts +++ b/packages/web/src/lib/virtualization.ts @@ -131,11 +131,6 @@ export const virtualize = (sheet: Sheet, e: HTMLDivElement | null): Virtualizati break; } } - // Scrolled past the last column (into autoExpand ghost columns): keep the trailing columns - // rendered so the table — and the ghost cells appended to it — stay in place. - if (boundaryLeft === 0 && sheet.numCols > 0) { - boundaryLeft = Math.max(sheet.numCols - OVERSCAN_X, 1); - } // Rows: binary-search the boundaries instead of accumulating heights from row 1. // The old linear scan was O(last-visible-row-index), so scrolling near the bottom // of a tall sheet cost O(numRows) per scroll event (~38ms at 1M rows). getOffsetTop(y) @@ -149,10 +144,7 @@ export const virtualize = (sheet: Sheet, e: HTMLDivElement | null): Virtualizati // First row whose bottom edge passes the viewport top / bottom (binarySearch returns // numRows + 1 when none does, i.e. scrolled past all content / content shorter than view). const topIdx = binarySearch(1, numRows, (y) => cumHeightThrough(y) > top, true); - // Scrolled past the last row (into autoExpand ghost rows): keep the trailing rows rendered so - // the table — and the ghost rows appended after them — stay in place. - boundaryTop = - topIdx > numRows ? (numRows > 0 ? Math.max(numRows - OVERSCAN_Y, 1) : 0) : Math.max(topIdx - OVERSCAN_Y, 1); + boundaryTop = topIdx > numRows ? 0 : Math.max(topIdx - OVERSCAN_Y, 1); // Remap only: the visible block is placed at physical offset adjTop = physTop - top + // before.height (see below). Near the top of a tall (capped) sheet there isn't enough // physical room above the scroll position for the full top overscan, so adjTop would go diff --git a/packages/web/src/styles/minified.ts b/packages/web/src/styles/minified.ts index 2f576a7c..e426c68c 100644 --- a/packages/web/src/styles/minified.ts +++ b/packages/web/src/styles/minified.ts @@ -1,3 +1,3 @@ // pnpm generate-style -export const LAST_MODIFIED = 1791034553; -export const CSS = `.gs-root1{display:inline-block;position:relative;border-spacing:0;width:fit-content;max-width:100%;overflow:auto;font-family:"SF Pro Text","SF Pro Icons","Helvetica Neue",Helvetica,Arial,Meiryo,sans-serif;visibility:hidden;opacity:0}.gs-root1.gs-initialized{visibility:visible;opacity:1;transition:opacity .2s ease-in-out}.gs-root1 .gs-main{flex:1;max-width:100%;overflow:hidden;position:relative;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box}.gs-root1 .gs-resizing{width:100%;height:100%;position:absolute;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 8%,transparent);top:0;left:0;z-index:2}.gs-root1 .gs-line-horizontal{width:100%}.gs-root1 .gs-line-vertical{height:100%}.gs-root1 .gs-line{position:relative;top:0;left:0;border:dotted 1px var(--gs-accent,#2563eb);box-sizing:border-box}.gs-root1 .gs-line span{font-size:10px;padding:3px;background-color:var(--gs-accent,#2563eb);color:#fff;margin:0;position:absolute;top:0;left:0}.gs-root1 .gs-scroll-handle{width:100%;height:100%;cursor:cell}.gs-hidden{visibility:hidden;position:absolute;top:0;left:0;width:0;height:0;overflow:hidden;pointer-events:none;z-index:-1}.gs-fixed{position:fixed;top:0;left:0;z-index:1}:where(.gs-root1[data-mode=light],.gs-editor[data-mode=light]){--gs-fg:#1f2328;--gs-muted-fg:#6b7280;--gs-border:#e3e6ea;--gs-bg:rgba(128, 128, 128, 0.07);--gs-canvas:transparent;--gs-surface:#ffffff;--gs-editor-surface:#ffffff;--gs-header-bg:#f4f5f7;--gs-header-fg:#59616b;--gs-accent:#2563eb}.gs-root1{background-color:var(--gs-bg);color:var(--gs-fg)}.gs-root1 .gs-main{background-color:var(--gs-canvas)}.gs-root1 .gs-tabular{background-color:var(--gs-canvas)}.gs-root1 .gs-sheet-body-data{background-color:var(--gs-surface)}.gs-root1 .gs-formula-bar{background-color:var(--gs-header-bg)}.gs-root1 .gs-formula-bar-editor-inner{color:var(--gs-fg)}.gs-root1 .gs-cell{border:solid 1px var(--gs-border)}.gs-root1 .gs-adjuster{background-color:var(--gs-border)}.gs-root1 .gs-tabular-inner{background-color:var(--gs-border)}.gs-root1 .gs-large-editor textarea{color:var(--gs-fg);caret-color:var(--gs-fg)}.gs-root1 .gs-th{background-color:var(--gs-header-bg);color:var(--gs-header-fg)}.gs-root1 .gs-th-top{border-left:solid 1px var(--gs-border)}.gs-root1 .gs-th-top .gs-th-inner{border-top:solid var(--gs-mx-bt,1px) var(--gs-border)}.gs-root1 .gs-th-left{border-top:solid 1px var(--gs-border)}.gs-root1 .gs-th-left .gs-th-inner{border-left:solid var(--gs-mx-bl,1px) var(--gs-border)}.gs-root1 .gs-search-bar{color:color-mix(in srgb,var(--gs-fg) 40%,transparent)}.gs-root1 .gs-search-bar textarea{color:var(--gs-fg);caret-color:var(--gs-fg)}.gs-editor.gs-editing textarea{caret-color:var(--gs-fg)}.gs-editor.gs-editing .gs-editor-hl{background-color:var(--gs-editor-surface);color:var(--gs-fg)}.gs-editor .gs-editor-options{color:var(--gs-fg);background-color:var(--gs-editor-surface);border:solid 1px var(--gs-border)}:where(.gs-root1[data-mode=dark],.gs-editor[data-mode=dark]){--gs-fg:#e4e6e9;--gs-muted-fg:#8b9096;--gs-border:#2c2f34;--gs-bg:rgba(128, 128, 128, 0.07);--gs-canvas:transparent;--gs-surface:#1c1e21;--gs-editor-surface:#1c1e21;--gs-header-bg:#212327;--gs-header-fg:#a6abb2;--gs-accent:#3b82f6}:where(.gs-root1[data-mode=auto],.gs-editor[data-mode=auto]){--gs-fg:#1f2328;--gs-muted-fg:#6b7280;--gs-border:#e3e6ea;--gs-bg:rgba(128, 128, 128, 0.07);--gs-canvas:transparent;--gs-surface:#ffffff;--gs-editor-surface:#ffffff;--gs-header-bg:#f4f5f7;--gs-header-fg:#59616b;--gs-accent:#2563eb}@media (prefers-color-scheme:dark){:where(.gs-root1[data-mode=auto],.gs-editor[data-mode=auto]){--gs-fg:#e4e6e9;--gs-muted-fg:#8b9096;--gs-border:#2c2f34;--gs-bg:rgba(128, 128, 128, 0.07);--gs-canvas:transparent;--gs-surface:#1c1e21;--gs-editor-surface:#1c1e21;--gs-header-bg:#212327;--gs-header-fg:#a6abb2;--gs-accent:#3b82f6}}:where(.gs-root1[data-mode=inherit-light],.gs-editor[data-mode=inherit-light]){--gs-fg:#1f2328;--gs-muted-fg:#6b7280;--gs-border:#e3e6ea;--gs-bg:rgba(128, 128, 128, 0.07);--gs-surface:#ffffff;--gs-editor-surface:#ffffff;--gs-header-bg:#f4f5f7;--gs-header-fg:#59616b;--gs-accent:#2563eb;--gs-bg:transparent;--gs-canvas:transparent;--gs-surface:transparent;--gs-header-bg:transparent}:where(.gs-root1[data-mode=inherit-dark],.gs-editor[data-mode=inherit-dark]){--gs-fg:#e4e6e9;--gs-muted-fg:#8b9096;--gs-border:#2c2f34;--gs-bg:rgba(128, 128, 128, 0.07);--gs-surface:#1c1e21;--gs-editor-surface:#1c1e21;--gs-header-bg:#212327;--gs-header-fg:#a6abb2;--gs-accent:#3b82f6;--gs-bg:transparent;--gs-canvas:transparent;--gs-surface:transparent;--gs-header-bg:transparent}.gs-root1[data-mode=inherit-dark] .gs-adjuster,.gs-root1[data-mode=inherit-dark] .gs-tabular-inner,.gs-root1[data-mode=inherit-light] .gs-adjuster,.gs-root1[data-mode=inherit-light] .gs-tabular-inner{background-color:transparent}.gs-root1[data-mode=inherit-light] .gs-th{background-color:rgba(128,128,128,.1);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}.gs-root1[data-mode=inherit-dark] .gs-th{background-color:rgba(128,128,128,.1);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}.gs-root1[data-gridlines=horizontal] .gs-cell{border-left-color:transparent;border-right-color:transparent}.gs-root1[data-gridlines=none] .gs-cell{border-color:transparent}.gs-root1[data-density=comfortable] .gs-cell-rendered{padding:0 10px}.gs-cell{transition:border-color .2s ease;padding:0;margin:0;box-sizing:border-box;position:relative;font-size:13px;letter-spacing:1px;line-height:24px;cursor:cell;user-select:none;-webkit-user-select:none;-moz-user-select:none}.gs-cell.gs-copying textarea:focus{outline:solid 1px var(--gs-accent,#2563eb)}.gs-cell.gs-selecting{z-index:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 7%,transparent)}.gs-cell.gs-selecting .gs-cell-label{display:block}.gs-cell.gs-choosing{margin-top:-1px;margin-left:-1px;z-index:1}.gs-cell.gs-choosing.gs-editing{color:transparent}.gs-cell.gs-choosing .gs-cell-label{display:block}.gs-cell.gs-pending .gs-cell-rendered{position:relative;overflow:hidden}.gs-cell.gs-pending .gs-cell-rendered::after{content:'';position:absolute;bottom:0;left:0;height:4px;width:40%;border-radius:1px;background:color-mix(in srgb,var(--gs-accent,#2563eb) 65%,transparent);animation:gs-pending-slide 1.4s ease-in-out infinite}.gs-cell .gs-formula-error-triangle{position:absolute;top:0;right:0;border-top:4px solid rgba(200,0,0,.9);border-right:4px solid rgba(200,0,0,.9);border-bottom:4px solid transparent;border-left:4px solid transparent;z-index:2;cursor:help}.gs-cell .gs-cell-label{font-size:10px;font-weight:500;font-style:normal;font-family:inherit;letter-spacing:.2px;line-height:1.4;position:absolute;top:0;right:0;background-color:var(--gs-accent,#2563eb);color:#fff;padding:1px 5px;border-bottom-left-radius:4px;display:none;opacity:.92}.gs-cell .gs-cell-inner-wrap{width:100%;height:100%;position:absolute;top:0;left:0}.gs-cell .gs-cell-inner{width:100%;height:100%;overflow:hidden;display:flex;box-sizing:border-box;border:none!important}.gs-cell .gs-cell-rendered{overflow:hidden;white-space:pre-wrap;cursor:cell;word-wrap:break-word;word-break:break-all;padding:0 6px;width:100%;height:100%}.gs-cell .gs-cell-rendered>*{position:relative}.gs-cell .gs-cell-rendered>.backface{z-index:0}.gs-cell .gs-autofill-drag{background-color:var(--gs-accent,#2563eb);position:absolute;width:7px;height:7px;bottom:0;right:0;cursor:crosshair;z-index:1}.gs-cell.gs-merged-host{z-index:1}.gs-cell.gs-merged-host.gs-selecting{background-color:transparent}.gs-cell.gs-merged-host.gs-selecting .gs-cell-inner-wrap{background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 7%,transparent)}.gs-cell.gs-merged-covered{z-index:0}.gs-th[data-x="1"] .gs-th-inner-wrap{border-left:none}.gs-th[data-y="1"] .gs-th-inner-wrap{border-top:none}.gs-formula-error-tooltip{position:fixed;background-color:rgba(35,8,8,.94);color:#fff;padding:6px 10px;border-radius:4px;border-left:3px solid rgba(220,50,50,.8);font-size:12px;line-height:1.5;max-width:260px;white-space:pre-wrap;word-break:break-word;box-shadow:0 3px 10px rgba(0,0,0,.4);z-index:100;pointer-events:none;letter-spacing:.3px}.gs-menu-modal{width:100%;height:100vh;z-index:12}.gs-label-input-label{font-size:13px;letter-spacing:1px}.gs-menu-divider{background-color:#aaa;padding:0;margin:5px 0;height:1px;list-style-type:none}.gs-menu-btn{position:absolute;background-color:rgba(128,128,128,.3);border:1px solid #ccc;border-radius:50%;cursor:pointer;font-size:12px;font-weight:700;line-height:1;color:#888;width:18px;height:18px;padding:0;display:flex;align-items:center;justify-content:center;opacity:0;transition:opacity .15s ease;z-index:2}.gs-context-menu{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;opacity:.9;transition:opacity .15s ease}.gs-context-menu:hover{opacity:1}.gs-context-menu .gs-menu-items{color:#555;margin:0;padding:0;min-width:250px}.gs-menu-item{padding:5px 10px;list-style-type:none;display:flex}.gs-menu-item.gs-enabled{cursor:pointer}.gs-menu-item.gs-enabled:hover{background-color:#eee}.gs-menu-item.gs-disabled{opacity:.5;cursor:not-allowed}.gs-menu-item .gs-menu-name{font-size:13px;letter-spacing:1px;flex:1}.gs-submenu-parent{position:relative;align-items:center}.gs-submenu-parent .gs-submenu-arrow{margin-left:8px;font-size:11px;opacity:.6}.gs-submenu-flyout{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;opacity:.9;transition:opacity .15s ease;min-width:200px;margin:0;color:#555;opacity:1;list-style-type:none}.gs-submenu-flyout:hover{opacity:1}.gs-menu-shortcut{font-size:10px;line-height:20px;color:#999}.gs-menu-shortcut:before{content:"( "}.gs-menu-shortcut:after{content:" )"}.gs-menu-shortcut .gs-menu-underline{text-decoration:underline}.gs-column-menu{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;opacity:.9;transition:opacity .15s ease}.gs-column-menu:hover{opacity:1}.gs-column-menu ul{color:#555;margin:0;padding:0;min-width:200px}.gs-column-menu .gs-column-menu-sort{align-items:center}.gs-column-menu .gs-column-menu-sort .gs-sort-buttons{display:flex;gap:4px;margin-left:auto}.gs-column-menu .gs-column-menu-sort .gs-sort-btn{font-size:12px;padding:4px 8px;border:1px solid transparent;border-radius:3px;background-color:rgba(180,180,180,.1);cursor:pointer;color:#555;font-weight:700;letter-spacing:.5px}.gs-column-menu .gs-column-menu-sort .gs-sort-btn:hover:not(:disabled){border-color:#555}.gs-column-menu .gs-column-menu-sort .gs-sort-btn:disabled{opacity:.5;cursor:not-allowed}.gs-column-menu .gs-column-menu-label{padding:5px 10px}.gs-column-menu .gs-label-input-row{display:flex;gap:4px;align-items:center}.gs-column-menu .gs-label-input{flex:1;font-size:13px;padding:4px 6px;border:none;border-bottom:1px solid #ccc;border-radius:0;outline:0;min-width:0;width:100px;background-color:transparent;box-shadow:none}.gs-column-menu .gs-label-input:focus{border-bottom-color:var(--gs-accent,#2563eb);outline:0;box-shadow:none}.gs-column-menu .gs-label-apply-btn{font-size:12px;padding:4px 8px;border:1px solid transparent;border-radius:3px;background-color:rgba(180,180,180,.1);cursor:pointer;color:#555;font-weight:700;letter-spacing:.5px}.gs-column-menu .gs-label-apply-btn:hover:not(:disabled){border-color:#555}.gs-column-menu .gs-label-apply-btn:disabled{opacity:.5;cursor:not-allowed}.gs-column-menu .gs-column-menu-filter{padding:5px 10px;list-style-type:none;font-size:13px}.gs-column-menu .gs-filter-header{display:flex;align-items:center;gap:8px}.gs-column-menu .gs-filter-header .gs-filter-add-btn{font-size:12px;padding:3px 9px;border:1px solid transparent;border-radius:3px;background-color:rgba(180,180,180,.1);cursor:pointer;color:#555;letter-spacing:1px}.gs-column-menu .gs-filter-header .gs-filter-add-btn:hover{border-color:#555}.gs-column-menu .gs-filter-mode-toggle{display:flex;gap:6px;margin-left:auto}.gs-column-menu .gs-filter-mode-toggle label{display:flex;align-items:center;gap:3px;font-size:11px;font-weight:700;letter-spacing:.5px;color:#888;cursor:pointer;user-select:none}.gs-column-menu .gs-filter-mode-toggle label input[type=radio]{margin:0;cursor:pointer}.gs-column-menu .gs-filter-mode-toggle label.gs-active{color:var(--gs-accent,#2563eb)}.gs-column-menu .gs-filter-mode-toggle.gs-disabled{opacity:.4;pointer-events:none}.gs-column-menu .gs-filter-conditions{display:flex;flex-direction:column;gap:5px;margin-top:6px;max-height:200px;overflow-y:auto}.gs-column-menu .gs-filter-condition-row{display:flex;gap:4px;align-items:normal}.gs-column-menu .gs-filter-method-select{font-size:12px;padding:4px 4px;border:none;border-bottom:1px solid #ccc;border-radius:0;outline:0;background-color:#fff;box-shadow:none;min-width:40px;max-width:80px;cursor:pointer}.gs-column-menu .gs-filter-method-select:focus{border-bottom-color:var(--gs-accent,#2563eb);outline:0;box-shadow:none}.gs-column-menu .gs-filter-value-input{flex:1;font-size:13px;padding:4px 6px;border:none;border-bottom:1px solid #ccc;border-radius:0;outline:0;min-width:0;width:80px;background-color:transparent;box-shadow:none}.gs-column-menu .gs-filter-value-input:focus{border-bottom-color:var(--gs-accent,#2563eb);outline:0;box-shadow:none}.gs-column-menu .gs-filter-remove-btn{font-size:12px;padding:0;border:none;border-radius:3px;background-color:transparent;cursor:pointer;color:#999;line-height:1;flex-shrink:0}.gs-column-menu .gs-filter-remove-btn:hover{color:#c33}.gs-column-menu .gs-filter-actions{display:flex;gap:4px;margin-top:10px;align-items:center}.gs-column-menu .gs-filter-actions .gs-filter-reset-all-btn{font-size:12px;padding:3px 9px;border:1px solid transparent;border-radius:3px;background-color:transparent;cursor:pointer;color:#c33;font-weight:700;letter-spacing:1px}.gs-column-menu .gs-filter-actions .gs-filter-reset-all-btn:hover{border-color:#c33}.gs-column-menu .gs-filter-actions .gs-filter-actions-right{display:flex;gap:4px;margin-left:auto}.gs-column-menu .gs-filter-actions .gs-filter-reset-btn{font-size:12px;padding:3px 9px;border:1px solid transparent;border-radius:3px;background-color:transparent;cursor:pointer;color:#e08000;font-weight:700;letter-spacing:1px}.gs-column-menu .gs-filter-actions .gs-filter-reset-btn:hover{border-color:#e08000}.gs-column-menu .gs-filter-actions .gs-filter-apply-btn{font-size:12px;padding:3px 6px;border:1px solid transparent;border-radius:3px;background-color:transparent;color:var(--gs-accent,#2563eb);cursor:pointer;font-weight:700;letter-spacing:1px}.gs-column-menu .gs-filter-actions .gs-filter-apply-btn:hover{border-color:var(--gs-accent,#2563eb)}.gs-column-menu-waiting{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:20px 30px;gap:12px;min-width:180px}.gs-column-menu-waiting .gs-waiting-message{font-size:13px;font-weight:700;color:#555;letter-spacing:.5px}.gs-column-menu-waiting .gs-waiting-spinner{width:24px;height:24px;border:3px solid #e0e0e0;border-top-color:var(--gs-accent,#2563eb);border-radius:50%;animation:spin .8s linear infinite}.gs-column-menu-waiting .gs-waiting-cancel-btn{font-size:12px;padding:4px 18px;border:1px solid #c33;border-radius:3px;background-color:transparent;color:#c33;cursor:pointer;font-weight:700;letter-spacing:1px}.gs-column-menu-waiting .gs-waiting-cancel-btn:hover{background-color:#c33;color:#fff}.gs-column-menu-btn{right:4px;top:50%;transform:translateY(-50%)}.gs-column-menu-btn.gs-filtered{opacity:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);border-color:var(--gs-accent,#2563eb);color:var(--gs-accent,#2563eb)}.gs-column-menu-btn.gs-active{opacity:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 18%,transparent);border-color:var(--gs-accent,#2563eb);color:var(--gs-accent,#2563eb)}.gs-th-top:hover .gs-column-menu-btn{opacity:1}.gs-row-menu{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;opacity:.9;transition:opacity .15s ease}.gs-row-menu:hover{opacity:1}.gs-row-menu ul{color:#555;margin:0;padding:0;min-width:200px}.gs-row-fixed-toggle{display:flex;align-items:center;gap:6px}.gs-row-fixed-check{font-size:12px;width:14px;text-align:center;color:transparent}.gs-row-fixed-check.gs-row-fixed-active{color:var(--gs-accent,#2563eb)}.gs-row-menu-btn{top:50%;transform:translateY(-50%);right:2px}.gs-row-menu-btn.gs-active{opacity:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 18%,transparent);border-color:var(--gs-accent,#2563eb);color:var(--gs-accent,#2563eb)}.gs-th-left:hover .gs-row-menu-btn{opacity:1}.gs-corner-menu-btn{bottom:2px;right:2px}.gs-corner-menu-btn:hover{opacity:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 18%,transparent);border-color:var(--gs-accent,#2563eb);color:var(--gs-accent,#2563eb)}.gs-th-left.gs-th-top:hover .gs-corner-menu-btn{opacity:1}.gs-editor-hl{padding:0 2px!important;position:absolute;font-family:monospace,Arial;font-size:12px;line-height:24px;letter-spacing:1px}.gs-formula-bar-editor-inner{position:relative;flex:1;min-width:0;display:flex;align-items:center}.gs-editor{opacity:0;z-index:-1}.gs-editor .gs-editor-inner{position:relative}.gs-editor .gs-editor-hl{box-sizing:content-box;border:solid 2px var(--gs-accent,#2563eb);margin:-2px -1px}.gs-editor textarea{width:100%;padding:0 2px!important;position:absolute;font-size:12px;font-family:monospace,Arial;line-height:24px;letter-spacing:1px;top:0;left:0;border:none;outline:0;background-color:transparent;color:transparent;resize:none;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;overflow:hidden;cursor:default;white-space:pre;height:auto}.gs-editor.gs-editing{z-index:11;opacity:1}.gs-editor.gs-editing .gs-cell-label{pointer-events:none;font-family:inherit;font-weight:500;position:absolute;top:0;right:0;margin-top:-17px;margin-right:-2px;padding:1px 5px;border-top-left-radius:4px;border-top-right-radius:4px;font-size:10px;background-color:var(--gs-accent,#2563eb);color:#fff;z-index:1}.gs-formula-bar{width:100%;position:relative;display:flex;align-items:stretch;box-sizing:border-box;border-style:solid;border-color:var(--gs-border,#e3e6ea);border-width:var(--gs-fb-bt,1px) var(--gs-fb-br,1px) var(--gs-fb-bb,1px) var(--gs-fb-bl,1px);padding:3px 6px;gap:6px}.gs-formula-bar .gs-selecting-address{display:flex;align-items:center;justify-content:center;min-width:38px;padding:0 4px;color:var(--gs-muted-fg,#6b7280);font-size:12px;font-variant-numeric:tabular-nums;text-align:center}.gs-formula-bar[data-spill=true]{background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 6%,var(--gs-header-bg,#f4f5f7))}.gs-formula-bar[data-spill=true] .gs-selecting-address{color:var(--gs-accent,#2563eb);font-style:italic}.gs-formula-bar[data-spill=true] .gs-selecting-address::after{content:"\\2196";margin-left:2px;font-style:normal;font-size:9px}.gs-formula-bar .gs-fx{display:flex;align-items:center;justify-content:center;align-self:center;width:26px;height:18px;flex-shrink:0;color:var(--gs-muted-fg,#6b7280);font-style:italic;font-family:inherit;font-weight:400;text-align:center;font-size:13px;letter-spacing:.3px;border-radius:4px;background-color:color-mix(in srgb,var(--gs-fg,#1f2328) 6%,transparent)}.gs-formula-bar .gs-editor-hl{z-index:0;overflow-y:auto;box-sizing:border-box;white-space:pre-wrap;word-break:break-all;text-align:left;line-height:24px}.gs-formula-bar textarea{position:relative;z-index:1;width:100%;vertical-align:bottom;color:transparent;border:none;background-color:transparent;padding:0 2px;box-sizing:border-box;text-align:left;outline:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;font-size:12px;font-family:monospace,Arial;height:24px;line-height:24px;min-height:24px;letter-spacing:1px;resize:vertical;caret-color:var(--gs-fg,#1f2328);white-space:pre-wrap;word-break:break-all}.gs-token-type-INVALID_REF{color:red}.gs-token-type-VALUE.gs-token-entity-type-boolean,.gs-token-type-VALUE.gs-token-entity-type-number{color:#39f}.gs-token-type-VALUE.gs-token-entity-type-string{color:#090}.gs-editor-options{position:fixed;z-index:1000;padding:4px;background:var(--gs-bg,#fff);box-shadow:0 4px 12px rgba(0,0,0,.15);border:1px solid rgba(0,0,0,.1);border-radius:6px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;overflow:visible}.gs-editor-option{position:relative;cursor:pointer;list-style:none;padding:6px 12px;font-size:13px;border-radius:4px;color:#333;margin-bottom:2px}.gs-editor-option-content{display:flex;justify-content:space-between;width:100%;align-items:center}.gs-editor-option-tab{font-size:10px;color:#aaa;margin-left:8px;padding:2px 4px;border:1px solid #ddd;border-radius:3px;background:#f9f9f9}.gs-editor-option:last-child{margin-bottom:0}.gs-editor-option:hover{background-color:#f5f5f5}.gs-editor-option-selected{background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);color:var(--gs-accent,#2563eb);font-weight:500}.gs-editor-option-selected:hover{background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 18%,transparent)}.gs-fn-guide1{position:absolute;top:-4px;left:calc(100% + 8px);background:#fff;border:1px solid rgba(0,0,0,.1);box-shadow:0 4px 16px rgba(0,0,0,.12);border-radius:6px;padding:16px;width:280px;z-index:1000;cursor:default;white-space:normal;color:#333}.gs-fn-guide1-tooltip{margin-bottom:8px;line-height:1.4;font-size:13px}.gs-fn-guide1-example{font-family:monospace;font-weight:600;font-size:13px;margin-bottom:8px;color:#1a1a1a;background:#f5f5f5;padding:6px 8px;border-radius:4px;border:1px solid #eee;display:flex;align-items:center;gap:6px;flex-wrap:wrap}.gs-fn-guide1-desc{font-size:13px;color:#555;margin-bottom:12px;line-height:1.4}.gs-fn-guide1-desc p{margin:0 0 6px 0}.gs-fn-guide1-desc p:last-child{margin-bottom:0}.gs-fn-guide1-args{border-top:1px solid #eee;padding-top:10px}.gs-fn-guide1-arg{margin-bottom:6px;line-height:1.4;font-size:12px}.gs-fn-guide1-arg-name{font-weight:600;color:var(--gs-accent,#2563eb)}.gs-fn-guide1-arg-opt{color:#888;font-size:11px}.gs-fn-guide1-arg-iter{font-weight:600;color:var(--gs-accent,#2563eb)}.gs-fn-guide1-arg-type{color:var(--gs-accent,#2563eb);padding:0 4px;background:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);border-radius:3px;font-size:11px;margin:0 4px}.gs-fn-guide1-arg-desc{color:#666}.gs-fn-guide-category{position:absolute;top:-11px;right:8px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;font-size:11px;font-weight:600;letter-spacing:.5px;text-transform:uppercase;padding:2px 7px;border-radius:4px;background:#e8eaf6;color:#3949ab;border:1px solid #c5cae9;white-space:nowrap}.gs-fn-guide-category.gs-fn-guide-category-math{background:#e3f2fd;color:#1565c0;border-color:#bbdefb}.gs-fn-guide-category.gs-fn-guide-category-statistics{background:#e8f5e9;color:#2e7d32;border-color:#c8e6c9}.gs-fn-guide-category.gs-fn-guide-category-text{background:#fff8e1;color:#f57f17;border-color:#ffecb3}.gs-fn-guide-category.gs-fn-guide-category-time{background:#fce4ec;color:#880e4f;border-color:#f8bbd0}.gs-fn-guide-category.gs-fn-guide-category-lookup{background:#f3e5f5;color:#6a1b9a;border-color:#e1bee7}.gs-fn-guide-category.gs-fn-guide-category-logical{background:#e0f2f1;color:#00695c;border-color:#b2dfdb}.gs-fn-guide-category.gs-fn-guide-category-information{background:#e0f7fa;color:#006064;border-color:#b2ebf2}.gs-fn-guide-category.gs-fn-guide-category-finance{background:#fff3e0;color:#e65100;border-color:#ffe0b2}.gs-fn-guide-category.gs-fn-guide-category-engineering{background:#efebe9;color:#4e342e;border-color:#d7ccc8}.gs-fn-guide-category.gs-fn-guide-category-ai{background:#e8eaf6;color:#3949ab;border-color:#c5cae9}.gs-fn-guide-category.gs-fn-guide-category-other{background:#f5f5f5;color:#616161;border-color:#e0e0e0}.gs-editor-portal{display:contents}.gs-editor-portal[data-mode=dark] .gs-editor-options,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-options,.gs-editor[data-mode=dark] .gs-editor-options,.gs-editor[data-mode=inherit-dark] .gs-editor-options{background:#252526;border-color:#454545;box-shadow:0 4px 12px rgba(0,0,0,.5)}.gs-editor-portal[data-mode=dark] .gs-editor-option,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option,.gs-editor[data-mode=dark] .gs-editor-option,.gs-editor[data-mode=inherit-dark] .gs-editor-option{color:#ccc}.gs-editor-portal[data-mode=dark] .gs-editor-option:hover,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option:hover,.gs-editor[data-mode=dark] .gs-editor-option:hover,.gs-editor[data-mode=inherit-dark] .gs-editor-option:hover{background-color:#333}.gs-editor-portal[data-mode=dark] .gs-editor-option-selected,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option-selected,.gs-editor[data-mode=dark] .gs-editor-option-selected,.gs-editor[data-mode=inherit-dark] .gs-editor-option-selected{background-color:#094771;color:#fff}.gs-editor-portal[data-mode=dark] .gs-editor-option-selected:hover,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option-selected:hover,.gs-editor[data-mode=dark] .gs-editor-option-selected:hover,.gs-editor[data-mode=inherit-dark] .gs-editor-option-selected:hover{background-color:#0d5a8f}.gs-editor-portal[data-mode=dark] .gs-editor-option-tab,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option-tab,.gs-editor[data-mode=dark] .gs-editor-option-tab,.gs-editor[data-mode=inherit-dark] .gs-editor-option-tab{color:#777;background:#333;border-color:#444}.gs-editor-portal[data-mode=dark] .gs-fn-guide1,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1,.gs-editor[data-mode=dark] .gs-fn-guide1,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1{background:#252526;border-color:#454545;color:#ccc}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-example,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-example,.gs-editor[data-mode=dark] .gs-fn-guide1-example,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-example{background:#1e1e1e;border-color:#333;color:#d4d4d4}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-desc,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-desc,.gs-editor[data-mode=dark] .gs-fn-guide1-desc,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-desc{color:#aaa}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-args,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-args,.gs-editor[data-mode=dark] .gs-fn-guide1-args,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-args{border-color:#333}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-iter,.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-name,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-iter,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-name,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-iter,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-name,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-iter,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-name{color:#4fc1ff}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-opt,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-opt,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-opt,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-opt{color:#777}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-type,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-type,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-type,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-type{background:#094771;color:#4fc1ff}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-desc,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-desc,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-desc,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-desc{color:#999}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category,.gs-editor[data-mode=dark] .gs-fn-guide-category,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category{background:#2a2d3e;color:#7986cb;border-color:#3d4166}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-math,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-math,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-math,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-math{background:#0d2137;color:#64b5f6;border-color:#1a3a5c}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-statistics,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-statistics,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-statistics,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-statistics{background:#0d2218;color:#66bb6a;border-color:#1a3d2a}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-text,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-text,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-text,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-text{background:#2e2200;color:#ffd54f;border-color:#4d3900}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-time,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-time,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-time,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-time{background:#2d0d1e;color:#f48fb1;border-color:#4d1a33}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-lookup,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-lookup,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-lookup,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-lookup{background:#260d33;color:#ce93d8;border-color:#3d1a54}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-logical,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-logical,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-logical,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-logical{background:#0d2421;color:#4db6ac;border-color:#1a3d39}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-information,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-information,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-information,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-information{background:#0d2426;color:#4dd0e1;border-color:#1a3d40}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-finance,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-finance,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-finance,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-finance{background:#2e1500;color:#ffb74d;border-color:#4d2800}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-engineering,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-engineering,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-engineering,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-engineering{background:#1e1714;color:#bcaaa4;border-color:#332c28}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-ai,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-ai,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-ai,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-ai{background:#10142e;color:#7986cb;border-color:#232a52}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-other,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-other,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-other,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-other{background:#1e1e1e;color:#9e9e9e;border-color:#333}.gs-editor-portal[data-mode=dark] .gs-fn-guide2,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2,.gs-editor[data-mode=dark] .gs-fn-guide2,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2{background:#252526;border-color:#454545;box-shadow:0 4px 12px rgba(0,0,0,.5);color:#ccc}.gs-editor-portal[data-mode=dark] .gs-fn-guide2-name,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2-name,.gs-editor[data-mode=dark] .gs-fn-guide2-name,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2-name{color:#dfdbdb;background:#333;border-color:#444}.gs-editor-portal[data-mode=dark] .gs-fn-guide2 .gs-active-arg,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2 .gs-active-arg,.gs-editor[data-mode=dark] .gs-fn-guide2 .gs-active-arg,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2 .gs-active-arg{color:#fff;background-color:#094771}.gs-editor-portal[data-mode=dark] .gs-fn-guide2-arg-type,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2-arg-type,.gs-editor[data-mode=dark] .gs-fn-guide2-arg-type,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2-arg-type{background:#094771;color:#4fc1ff}.gs-editor-portal[data-mode=dark] .gs-fn-guide2-desc,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2-desc,.gs-editor[data-mode=dark] .gs-fn-guide2-desc,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2-desc{color:#aaa;border-top-color:#333}.gs-fn-guide2{position:fixed;left:0;background:#fff;border:1px solid rgba(0,0,0,.1);box-shadow:0 4px 16px rgba(0,0,0,.12);border-radius:6px;padding:12px 16px;width:280px;z-index:1000;cursor:default;white-space:normal;color:#333;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;transition:opacity .1s ease-in-out}.gs-fn-guide2.gs-fn-guide2-hidden{opacity:0!important;pointer-events:none!important}.gs-fn-guide2-name{font-family:monospace;font-weight:700;font-size:13px;color:#1a1a1a;background:#f5f5f5;padding:6px 8px;border-radius:4px;border:1px solid #eee;display:flex;align-items:center;gap:6px;flex-wrap:wrap;width:100%;box-sizing:border-box;margin-bottom:8px}.gs-fn-guide2-args-inline{font-size:13px;font-family:monospace;line-height:1.5;margin-bottom:8px;color:#666}.gs-fn-guide2-args-inline span{transition:all .2s ease-in-out}.gs-fn-guide2 .gs-active-arg{font-weight:700;color:var(--gs-accent,#2563eb);background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);padding:2px 4px;margin:0 -4px;border-radius:4px}.gs-fn-guide2-arg-type{color:var(--gs-accent,#2563eb);padding:0 4px;background:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);border-radius:3px;font-size:11px;margin:0 4px}.gs-fn-guide2-desc{font-size:12px;color:#555;line-height:1.4;border-top:1px solid #eee;padding-top:8px;margin-top:4px}.gs-fn-guide2-desc p{margin:0}.gs-fn-guide2-desc-more{font-style:italic;color:#888;margin-top:4px!important;font-size:11px}.gs-adjuster{padding:0}.gs-table{margin:0}.gs-tabular{overflow:auto;overflow-anchor:none;display:flex;box-sizing:border-box;position:relative}.gs-root1[data-matrix-align=both] .gs-tabular,.gs-root1[data-matrix-align=horizontal] .gs-tabular{justify-content:safe center}.gs-root1[data-matrix-align=both] .gs-tabular,.gs-root1[data-matrix-align=vertical] .gs-tabular{align-items:safe center}.gs-tabular-inner{flex:0 0 auto;position:relative;overflow:hidden;overflow:clip;box-sizing:border-box;border-right:solid var(--gs-mx-br,1px) var(--gs-border,#e3e6ea);border-bottom:solid var(--gs-mx-bb,1px) var(--gs-border,#e3e6ea)}.gs-tabular-inner>table{table-layout:fixed;border-collapse:collapse;border-spacing:0}.gs-ghost-cell{padding:0;box-sizing:border-box;border:dashed 1px var(--gs-border,#e3e6ea);background-color:var(--gs-surface,#fff);opacity:.5;cursor:crosshair}.gs-ghost-th{opacity:.5}.gs-ghost-th-top{top:0}.gs-ghost-th-left{left:0}.gs-main[data-overflow-x=true] .gs-tabular-inner{border-right-width:0}.gs-main[data-overflow-y=true] .gs-tabular-inner{border-bottom-width:0}.gs-main::after{content:'';position:absolute;inset:0;pointer-events:none;z-index:3;border:0 solid var(--gs-border,#e3e6ea)}.gs-main[data-overflow-x=true]::after{border-right-width:var(--gs-mx-br,1px)}.gs-main[data-overflow-y=true]::after{border-bottom-width:var(--gs-mx-bb,1px)}.gs-th{z-index:2;padding:0;position:sticky;font-size:13px;font-weight:400;box-sizing:border-box;vertical-align:top}.gs-th .gs-resizer{position:absolute;border-color:transparent;box-sizing:border-box;z-index:2}.gs-th .gs-resizer:hover{background-color:var(--gs-accent,#2563eb)}.gs-th .gs-resizer.gs-protected{display:none}.gs-th-inner{height:100%;box-sizing:border-box;vertical-align:middle;overflow:hidden;display:flex;align-items:center;justify-content:center}.gs-th-inner-wrap{height:100%;box-sizing:border-box;background-color:transparent}.gs-th-top{top:0;overflow:hidden}.gs-th-top .gs-resizer{top:0;right:0;width:3px;cursor:e-resize}.gs-th-top .gs-resizer.gs-dragging{border-right-style:dotted;height:1000000px!important;cursor:e-resize}.gs-th-left{left:0;overflow:hidden;min-width:30px;border-top:solid 1px var(--gs-border,#e3e6ea)}.gs-th-left .gs-resizer{left:0;bottom:0;height:3px;cursor:n-resize}.gs-th-left .gs-resizer.gs-dragging{border-bottom-style:dotted;width:1000000px!important;cursor:n-resize}.gs-th-top.gs-th-left{top:0;left:0;z-index:3;border:none!important}.gs-th-left.gs-filter-fixed .gs-th-inner::before{content:'‹\\00a0'}.gs-th-left.gs-sort-fixed .gs-th-inner::after{content:'\\00a0›'}.gs-col-addr{position:absolute;top:2px;right:4px;font-size:9px;opacity:.5;line-height:1;letter-spacing:.3px;pointer-events:none}.gs-search-bar{width:100%;display:flex;align-items:center;padding:3px 0;border-top:solid 1px rgba(128,128,128,.3);border-left:solid 1px rgba(128,128,128,.3);border-right:solid 1px rgba(128,128,128,.3);border-bottom:solid 1px rgba(128,128,128,.3);box-sizing:border-box;background-color:rgba(200,50,0,.2)}.gs-search-bar.gs-search-found{background-color:rgba(0,200,100,.2)}.gs-search-bar .gs-search-bar-inner{border-left:solid 1px rgba(128,128,128,.5)}.gs-search-bar .gs-search-bar-icon{border-left:solid 1px rgba(128,128,128,.3);display:flex;align-items:center;justify-content:center;width:30px;flex-shrink:0}.gs-search-bar .gs-search-input-wrapper{flex-grow:1;position:relative;display:flex;align-items:center;height:100%}.gs-search-bar .gs-search-input-ghost{position:absolute;left:2px;right:2px;top:0;bottom:0;pointer-events:none;font-size:12px;font-family:monospace,Arial;line-height:24px;letter-spacing:1px;white-space:pre-wrap;word-break:break-all;color:transparent;overflow:hidden}.gs-search-bar .gs-search-input-ghost .gs-search-ghost-hint{color:#aaa}.gs-search-bar textarea{background-color:transparent;border:none;padding:0 2px;box-sizing:border-box;outline:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;font-size:12px;font-family:monospace,Arial;height:24px;line-height:24px;min-height:24px;letter-spacing:1px;caret-color:rgba(128,128,128);white-space:pre-wrap;word-break:break-all;flex-grow:1;width:100%;resize:none}.gs-search-progress{color:#999;font-size:13px;width:60px;flex-shrink:0;white-space:nowrap;text-align:center}.gs-search-close{cursor:pointer;display:flex;align-items:center;justify-content:center;width:24px;flex-shrink:0}.gs-search-buttons{display:flex;align-items:center;white-space:nowrap;flex-shrink:0}.gs-search-button{display:inline-flex;cursor:pointer;margin:0 2px}.gs-search-button span{display:inline-block;font-size:11px;padding:3px 5px;background-color:rgba(128,128,128,.1);border:1px solid rgba(128,128,128,.3);border-radius:3px;transition:all .15s ease;line-height:1}.gs-search-button span:hover{background-color:rgba(128,128,128,.2)}.gs-search-button span.gs-search-button-on{color:var(--gs-accent,#2563eb);background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 22%,transparent);border-color:var(--gs-accent,#2563eb)}.gs-search-range span{white-space:nowrap;font-family:monospace}@keyframes spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}.gs-loading-overlay{position:absolute;top:0;left:0;right:0;bottom:0;background:color-mix(in srgb,var(--gs-surface,#fff) 70%,transparent);display:flex;align-items:center;justify-content:center;z-index:100;pointer-events:all}.gs-loading-spinner{width:32px;height:32px;border:3px solid color-mix(in srgb,var(--gs-fg,#1f2328) 12%,transparent);border-top-color:var(--gs-accent,#2563eb);border-radius:50%;animation:spin .8s linear infinite}.gs-progress-overlay{position:absolute;top:0;left:0;right:0;bottom:0;z-index:100;pointer-events:all;display:flex;align-items:center;justify-content:center}.gs-progress-box{min-width:240px;padding:16px 18px;border-radius:8px;background:var(--gs-editor-surface,#fff);border:1px solid var(--gs-border,#e3e6ea);box-shadow:0 6px 24px rgba(0,0,0,.28);display:flex;flex-direction:column;gap:10px}.gs-progress-head{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--gs-fg,#1f2328)}.gs-progress-head .gs-loading-spinner{width:15px;height:15px;border-width:2px}.gs-progress-track{height:6px;border-radius:3px;overflow:hidden;background:color-mix(in srgb,var(--gs-fg,#1f2328) 12%,transparent)}.gs-progress-fill{height:100%;border-radius:3px;background:var(--gs-accent,#2563eb);transition:width .1s linear}@keyframes gs-pending-slide{0%{left:-40%}100%{left:100%}}@keyframes gs-pending-pulse{0%{left:0;width:0}50%{left:0;width:100%}100%{left:100%;width:0}}@keyframes gs-flash{0%{opacity:0}20%{opacity:1}100%{opacity:0}}.gs-flash-overlay{position:absolute;inset:0;pointer-events:none;z-index:9999;background:color-mix(in srgb,var(--gs-accent,#2563eb) 15%,transparent);opacity:0}.gs-flash-overlay--active{animation:gs-flash .6s ease-out forwards}`; +export const LAST_MODIFIED = 1791139181; +export const CSS = `.gs-root1{display:inline-block;position:relative;border-spacing:0;width:fit-content;max-width:100%;overflow:auto;font-family:"SF Pro Text","SF Pro Icons","Helvetica Neue",Helvetica,Arial,Meiryo,sans-serif;visibility:hidden;opacity:0}.gs-root1.gs-initialized{visibility:visible;opacity:1;transition:opacity .2s ease-in-out}.gs-root1 .gs-main{flex:1;max-width:100%;overflow:hidden;position:relative;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box}.gs-root1 .gs-resizing{width:100%;height:100%;position:absolute;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 8%,transparent);top:0;left:0;z-index:2}.gs-root1 .gs-line-horizontal{width:100%}.gs-root1 .gs-line-vertical{height:100%}.gs-root1 .gs-line{position:relative;top:0;left:0;border:dotted 1px var(--gs-accent,#2563eb);box-sizing:border-box}.gs-root1 .gs-line span{font-size:10px;padding:3px;background-color:var(--gs-accent,#2563eb);color:#fff;margin:0;position:absolute;top:0;left:0}.gs-root1 .gs-scroll-handle{width:100%;height:100%;cursor:cell}.gs-hidden{visibility:hidden;position:absolute;top:0;left:0;width:0;height:0;overflow:hidden;pointer-events:none;z-index:-1}.gs-fixed{position:fixed;top:0;left:0;z-index:1}:where(.gs-root1[data-mode=light],.gs-editor[data-mode=light]){--gs-fg:#1f2328;--gs-muted-fg:#6b7280;--gs-border:#e3e6ea;--gs-bg:rgba(128, 128, 128, 0.07);--gs-canvas:transparent;--gs-surface:#ffffff;--gs-editor-surface:#ffffff;--gs-header-bg:#f4f5f7;--gs-header-fg:#59616b;--gs-accent:#2563eb}.gs-root1{background-color:var(--gs-bg);color:var(--gs-fg)}.gs-root1 .gs-main{background-color:var(--gs-canvas)}.gs-root1 .gs-tabular{background-color:var(--gs-canvas)}.gs-root1 .gs-sheet-body-data{background-color:var(--gs-surface)}.gs-root1 .gs-formula-bar{background-color:var(--gs-header-bg)}.gs-root1 .gs-formula-bar-editor-inner{color:var(--gs-fg)}.gs-root1 .gs-cell{border:solid 1px var(--gs-border)}.gs-root1 .gs-adjuster{background-color:var(--gs-border)}.gs-root1 .gs-tabular-inner{background-color:var(--gs-border)}.gs-root1 .gs-large-editor textarea{color:var(--gs-fg);caret-color:var(--gs-fg)}.gs-root1 .gs-th{background-color:var(--gs-header-bg);color:var(--gs-header-fg)}.gs-root1 .gs-th-top{border-left:solid 1px var(--gs-border)}.gs-root1 .gs-th-top .gs-th-inner{border-top:solid var(--gs-mx-bt,1px) var(--gs-border)}.gs-root1 .gs-th-left{border-top:solid 1px var(--gs-border)}.gs-root1 .gs-th-left .gs-th-inner{border-left:solid var(--gs-mx-bl,1px) var(--gs-border)}.gs-root1 .gs-search-bar{color:color-mix(in srgb,var(--gs-fg) 40%,transparent)}.gs-root1 .gs-search-bar textarea{color:var(--gs-fg);caret-color:var(--gs-fg)}.gs-editor.gs-editing textarea{caret-color:var(--gs-fg)}.gs-editor.gs-editing .gs-editor-hl{background-color:var(--gs-editor-surface);color:var(--gs-fg)}.gs-editor .gs-editor-options{color:var(--gs-fg);background-color:var(--gs-editor-surface);border:solid 1px var(--gs-border)}:where(.gs-root1[data-mode=dark],.gs-editor[data-mode=dark]){--gs-fg:#e4e6e9;--gs-muted-fg:#8b9096;--gs-border:#2c2f34;--gs-bg:rgba(128, 128, 128, 0.07);--gs-canvas:transparent;--gs-surface:#1c1e21;--gs-editor-surface:#1c1e21;--gs-header-bg:#212327;--gs-header-fg:#a6abb2;--gs-accent:#3b82f6}:where(.gs-root1[data-mode=auto],.gs-editor[data-mode=auto]){--gs-fg:#1f2328;--gs-muted-fg:#6b7280;--gs-border:#e3e6ea;--gs-bg:rgba(128, 128, 128, 0.07);--gs-canvas:transparent;--gs-surface:#ffffff;--gs-editor-surface:#ffffff;--gs-header-bg:#f4f5f7;--gs-header-fg:#59616b;--gs-accent:#2563eb}@media (prefers-color-scheme:dark){:where(.gs-root1[data-mode=auto],.gs-editor[data-mode=auto]){--gs-fg:#e4e6e9;--gs-muted-fg:#8b9096;--gs-border:#2c2f34;--gs-bg:rgba(128, 128, 128, 0.07);--gs-canvas:transparent;--gs-surface:#1c1e21;--gs-editor-surface:#1c1e21;--gs-header-bg:#212327;--gs-header-fg:#a6abb2;--gs-accent:#3b82f6}}:where(.gs-root1[data-mode=inherit-light],.gs-editor[data-mode=inherit-light]){--gs-fg:#1f2328;--gs-muted-fg:#6b7280;--gs-border:#e3e6ea;--gs-bg:rgba(128, 128, 128, 0.07);--gs-surface:#ffffff;--gs-editor-surface:#ffffff;--gs-header-bg:#f4f5f7;--gs-header-fg:#59616b;--gs-accent:#2563eb;--gs-bg:transparent;--gs-canvas:transparent;--gs-surface:transparent;--gs-header-bg:transparent}:where(.gs-root1[data-mode=inherit-dark],.gs-editor[data-mode=inherit-dark]){--gs-fg:#e4e6e9;--gs-muted-fg:#8b9096;--gs-border:#2c2f34;--gs-bg:rgba(128, 128, 128, 0.07);--gs-surface:#1c1e21;--gs-editor-surface:#1c1e21;--gs-header-bg:#212327;--gs-header-fg:#a6abb2;--gs-accent:#3b82f6;--gs-bg:transparent;--gs-canvas:transparent;--gs-surface:transparent;--gs-header-bg:transparent}.gs-root1[data-mode=inherit-dark] .gs-adjuster,.gs-root1[data-mode=inherit-dark] .gs-tabular-inner,.gs-root1[data-mode=inherit-light] .gs-adjuster,.gs-root1[data-mode=inherit-light] .gs-tabular-inner{background-color:transparent}.gs-root1[data-mode=inherit-light] .gs-th{background-color:rgba(128,128,128,.1);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}.gs-root1[data-mode=inherit-dark] .gs-th{background-color:rgba(128,128,128,.1);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}.gs-root1[data-gridlines=horizontal] .gs-cell{border-left-color:transparent;border-right-color:transparent}.gs-root1[data-gridlines=none] .gs-cell{border-color:transparent}.gs-root1[data-density=comfortable] .gs-cell-rendered{padding:0 10px}.gs-cell{transition:border-color .2s ease;padding:0;margin:0;box-sizing:border-box;position:relative;font-size:13px;letter-spacing:1px;line-height:24px;cursor:cell;user-select:none;-webkit-user-select:none;-moz-user-select:none}.gs-cell.gs-copying textarea:focus{outline:solid 1px var(--gs-accent,#2563eb)}.gs-cell.gs-selecting{z-index:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 7%,transparent)}.gs-cell.gs-selecting .gs-cell-label{display:block}.gs-cell.gs-choosing{margin-top:-1px;margin-left:-1px;z-index:1}.gs-cell.gs-choosing.gs-editing{color:transparent}.gs-cell.gs-choosing .gs-cell-label{display:block}.gs-cell.gs-pending .gs-cell-rendered{position:relative;overflow:hidden}.gs-cell.gs-pending .gs-cell-rendered::after{content:'';position:absolute;bottom:0;left:0;height:4px;width:40%;border-radius:1px;background:color-mix(in srgb,var(--gs-accent,#2563eb) 65%,transparent);animation:gs-pending-slide 1.4s ease-in-out infinite}.gs-cell .gs-formula-error-triangle{position:absolute;top:0;right:0;border-top:4px solid rgba(200,0,0,.9);border-right:4px solid rgba(200,0,0,.9);border-bottom:4px solid transparent;border-left:4px solid transparent;z-index:2;cursor:help}.gs-cell .gs-cell-label{font-size:10px;font-weight:500;font-style:normal;font-family:inherit;letter-spacing:.2px;line-height:1.4;position:absolute;top:0;right:0;background-color:var(--gs-accent,#2563eb);color:#fff;padding:1px 5px;border-bottom-left-radius:4px;display:none;opacity:.92}.gs-cell .gs-cell-inner-wrap{width:100%;height:100%;position:absolute;top:0;left:0}.gs-cell .gs-cell-inner{width:100%;height:100%;overflow:hidden;display:flex;box-sizing:border-box;border:none!important}.gs-cell .gs-cell-rendered{overflow:hidden;white-space:pre-wrap;cursor:cell;word-wrap:break-word;word-break:break-all;padding:0 6px;width:100%;height:100%}.gs-cell .gs-cell-rendered>*{position:relative}.gs-cell .gs-cell-rendered>.backface{z-index:0}.gs-cell .gs-autofill-drag{background-color:var(--gs-accent,#2563eb);position:absolute;width:7px;height:7px;bottom:0;right:0;cursor:crosshair;z-index:1}.gs-cell.gs-merged-host{z-index:1}.gs-cell.gs-merged-host.gs-selecting{background-color:transparent}.gs-cell.gs-merged-host.gs-selecting .gs-cell-inner-wrap{background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 7%,transparent)}.gs-cell.gs-merged-covered{z-index:0}.gs-th[data-x="1"] .gs-th-inner-wrap{border-left:none}.gs-th[data-y="1"] .gs-th-inner-wrap{border-top:none}.gs-formula-error-tooltip{position:fixed;background-color:rgba(35,8,8,.94);color:#fff;padding:6px 10px;border-radius:4px;border-left:3px solid rgba(220,50,50,.8);font-size:12px;line-height:1.5;max-width:260px;white-space:pre-wrap;word-break:break-word;box-shadow:0 3px 10px rgba(0,0,0,.4);z-index:100;pointer-events:none;letter-spacing:.3px}.gs-menu-modal{width:100%;height:100vh;z-index:12}.gs-label-input-label{font-size:13px;letter-spacing:1px}.gs-menu-divider{background-color:#aaa;padding:0;margin:5px 0;height:1px;list-style-type:none}.gs-menu-btn{position:absolute;background-color:rgba(128,128,128,.3);border:1px solid #ccc;border-radius:50%;cursor:pointer;font-size:12px;font-weight:700;line-height:1;color:#888;width:18px;height:18px;padding:0;display:flex;align-items:center;justify-content:center;opacity:0;transition:opacity .15s ease;z-index:2}.gs-context-menu{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;opacity:.9;transition:opacity .15s ease}.gs-context-menu:hover{opacity:1}.gs-context-menu .gs-menu-items{color:#555;margin:0;padding:0;min-width:250px}.gs-menu-item{padding:5px 10px;list-style-type:none;display:flex}.gs-menu-item.gs-enabled{cursor:pointer}.gs-menu-item.gs-enabled:hover{background-color:#eee}.gs-menu-item.gs-disabled{opacity:.5;cursor:not-allowed}.gs-menu-item .gs-menu-name{font-size:13px;letter-spacing:1px;flex:1}.gs-submenu-parent{position:relative;align-items:center}.gs-submenu-parent .gs-submenu-arrow{margin-left:8px;font-size:11px;opacity:.6}.gs-submenu-flyout{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;opacity:.9;transition:opacity .15s ease;min-width:200px;margin:0;color:#555;opacity:1;list-style-type:none}.gs-submenu-flyout:hover{opacity:1}.gs-menu-shortcut{font-size:10px;line-height:20px;color:#999}.gs-menu-shortcut:before{content:"( "}.gs-menu-shortcut:after{content:" )"}.gs-menu-shortcut .gs-menu-underline{text-decoration:underline}.gs-column-menu{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;opacity:.9;transition:opacity .15s ease}.gs-column-menu:hover{opacity:1}.gs-column-menu ul{color:#555;margin:0;padding:0;min-width:200px}.gs-column-menu .gs-column-menu-sort{align-items:center}.gs-column-menu .gs-column-menu-sort .gs-sort-buttons{display:flex;gap:4px;margin-left:auto}.gs-column-menu .gs-column-menu-sort .gs-sort-btn{font-size:12px;padding:4px 8px;border:1px solid transparent;border-radius:3px;background-color:rgba(180,180,180,.1);cursor:pointer;color:#555;font-weight:700;letter-spacing:.5px}.gs-column-menu .gs-column-menu-sort .gs-sort-btn:hover:not(:disabled){border-color:#555}.gs-column-menu .gs-column-menu-sort .gs-sort-btn:disabled{opacity:.5;cursor:not-allowed}.gs-column-menu .gs-column-menu-label{padding:5px 10px}.gs-column-menu .gs-label-input-row{display:flex;gap:4px;align-items:center}.gs-column-menu .gs-label-input{flex:1;font-size:13px;padding:4px 6px;border:none;border-bottom:1px solid #ccc;border-radius:0;outline:0;min-width:0;width:100px;background-color:transparent;box-shadow:none}.gs-column-menu .gs-label-input:focus{border-bottom-color:var(--gs-accent,#2563eb);outline:0;box-shadow:none}.gs-column-menu .gs-label-apply-btn{font-size:12px;padding:4px 8px;border:1px solid transparent;border-radius:3px;background-color:rgba(180,180,180,.1);cursor:pointer;color:#555;font-weight:700;letter-spacing:.5px}.gs-column-menu .gs-label-apply-btn:hover:not(:disabled){border-color:#555}.gs-column-menu .gs-label-apply-btn:disabled{opacity:.5;cursor:not-allowed}.gs-column-menu .gs-column-menu-filter{padding:5px 10px;list-style-type:none;font-size:13px}.gs-column-menu .gs-filter-header{display:flex;align-items:center;gap:8px}.gs-column-menu .gs-filter-header .gs-filter-add-btn{font-size:12px;padding:3px 9px;border:1px solid transparent;border-radius:3px;background-color:rgba(180,180,180,.1);cursor:pointer;color:#555;letter-spacing:1px}.gs-column-menu .gs-filter-header .gs-filter-add-btn:hover{border-color:#555}.gs-column-menu .gs-filter-mode-toggle{display:flex;gap:6px;margin-left:auto}.gs-column-menu .gs-filter-mode-toggle label{display:flex;align-items:center;gap:3px;font-size:11px;font-weight:700;letter-spacing:.5px;color:#888;cursor:pointer;user-select:none}.gs-column-menu .gs-filter-mode-toggle label input[type=radio]{margin:0;cursor:pointer}.gs-column-menu .gs-filter-mode-toggle label.gs-active{color:var(--gs-accent,#2563eb)}.gs-column-menu .gs-filter-mode-toggle.gs-disabled{opacity:.4;pointer-events:none}.gs-column-menu .gs-filter-conditions{display:flex;flex-direction:column;gap:5px;margin-top:6px;max-height:200px;overflow-y:auto}.gs-column-menu .gs-filter-condition-row{display:flex;gap:4px;align-items:normal}.gs-column-menu .gs-filter-method-select{font-size:12px;padding:4px 4px;border:none;border-bottom:1px solid #ccc;border-radius:0;outline:0;background-color:#fff;box-shadow:none;min-width:40px;max-width:80px;cursor:pointer}.gs-column-menu .gs-filter-method-select:focus{border-bottom-color:var(--gs-accent,#2563eb);outline:0;box-shadow:none}.gs-column-menu .gs-filter-value-input{flex:1;font-size:13px;padding:4px 6px;border:none;border-bottom:1px solid #ccc;border-radius:0;outline:0;min-width:0;width:80px;background-color:transparent;box-shadow:none}.gs-column-menu .gs-filter-value-input:focus{border-bottom-color:var(--gs-accent,#2563eb);outline:0;box-shadow:none}.gs-column-menu .gs-filter-remove-btn{font-size:12px;padding:0;border:none;border-radius:3px;background-color:transparent;cursor:pointer;color:#999;line-height:1;flex-shrink:0}.gs-column-menu .gs-filter-remove-btn:hover{color:#c33}.gs-column-menu .gs-filter-actions{display:flex;gap:4px;margin-top:10px;align-items:center}.gs-column-menu .gs-filter-actions .gs-filter-reset-all-btn{font-size:12px;padding:3px 9px;border:1px solid transparent;border-radius:3px;background-color:transparent;cursor:pointer;color:#c33;font-weight:700;letter-spacing:1px}.gs-column-menu .gs-filter-actions .gs-filter-reset-all-btn:hover{border-color:#c33}.gs-column-menu .gs-filter-actions .gs-filter-actions-right{display:flex;gap:4px;margin-left:auto}.gs-column-menu .gs-filter-actions .gs-filter-reset-btn{font-size:12px;padding:3px 9px;border:1px solid transparent;border-radius:3px;background-color:transparent;cursor:pointer;color:#e08000;font-weight:700;letter-spacing:1px}.gs-column-menu .gs-filter-actions .gs-filter-reset-btn:hover{border-color:#e08000}.gs-column-menu .gs-filter-actions .gs-filter-apply-btn{font-size:12px;padding:3px 6px;border:1px solid transparent;border-radius:3px;background-color:transparent;color:var(--gs-accent,#2563eb);cursor:pointer;font-weight:700;letter-spacing:1px}.gs-column-menu .gs-filter-actions .gs-filter-apply-btn:hover{border-color:var(--gs-accent,#2563eb)}.gs-column-menu-waiting{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:20px 30px;gap:12px;min-width:180px}.gs-column-menu-waiting .gs-waiting-message{font-size:13px;font-weight:700;color:#555;letter-spacing:.5px}.gs-column-menu-waiting .gs-waiting-spinner{width:24px;height:24px;border:3px solid #e0e0e0;border-top-color:var(--gs-accent,#2563eb);border-radius:50%;animation:spin .8s linear infinite}.gs-column-menu-waiting .gs-waiting-cancel-btn{font-size:12px;padding:4px 18px;border:1px solid #c33;border-radius:3px;background-color:transparent;color:#c33;cursor:pointer;font-weight:700;letter-spacing:1px}.gs-column-menu-waiting .gs-waiting-cancel-btn:hover{background-color:#c33;color:#fff}.gs-column-menu-btn{right:4px;top:50%;transform:translateY(-50%)}.gs-column-menu-btn.gs-filtered{opacity:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);border-color:var(--gs-accent,#2563eb);color:var(--gs-accent,#2563eb)}.gs-column-menu-btn.gs-active{opacity:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 18%,transparent);border-color:var(--gs-accent,#2563eb);color:var(--gs-accent,#2563eb)}.gs-th-top:hover .gs-column-menu-btn{opacity:1}.gs-row-menu{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;opacity:.9;transition:opacity .15s ease}.gs-row-menu:hover{opacity:1}.gs-row-menu ul{color:#555;margin:0;padding:0;min-width:200px}.gs-row-fixed-toggle{display:flex;align-items:center;gap:6px}.gs-row-fixed-check{font-size:12px;width:14px;text-align:center;color:transparent}.gs-row-fixed-check.gs-row-fixed-active{color:var(--gs-accent,#2563eb)}.gs-row-menu-btn{top:50%;transform:translateY(-50%);right:2px}.gs-row-menu-btn.gs-active{opacity:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 18%,transparent);border-color:var(--gs-accent,#2563eb);color:var(--gs-accent,#2563eb)}.gs-th-left:hover .gs-row-menu-btn{opacity:1}.gs-corner-menu-btn{bottom:2px;right:2px}.gs-corner-menu-btn:hover{opacity:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 18%,transparent);border-color:var(--gs-accent,#2563eb);color:var(--gs-accent,#2563eb)}.gs-th-left.gs-th-top:hover .gs-corner-menu-btn{opacity:1}.gs-editor-hl{padding:0 2px!important;position:absolute;font-family:monospace,Arial;font-size:12px;line-height:24px;letter-spacing:1px}.gs-formula-bar-editor-inner{position:relative;flex:1;min-width:0;display:flex;align-items:center}.gs-editor{opacity:0;z-index:-1}.gs-editor .gs-editor-inner{position:relative}.gs-editor .gs-editor-hl{box-sizing:content-box;border:solid 2px var(--gs-accent,#2563eb);margin:-2px -1px}.gs-editor textarea{width:100%;padding:0 2px!important;position:absolute;font-size:12px;font-family:monospace,Arial;line-height:24px;letter-spacing:1px;top:0;left:0;border:none;outline:0;background-color:transparent;color:transparent;resize:none;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;overflow:hidden;cursor:default;white-space:pre;height:auto}.gs-editor.gs-editing{z-index:11;opacity:1}.gs-editor.gs-editing .gs-cell-label{pointer-events:none;font-family:inherit;font-weight:500;position:absolute;top:0;right:0;margin-top:-17px;margin-right:-2px;padding:1px 5px;border-top-left-radius:4px;border-top-right-radius:4px;font-size:10px;background-color:var(--gs-accent,#2563eb);color:#fff;z-index:1}.gs-formula-bar{width:100%;position:relative;display:flex;align-items:stretch;box-sizing:border-box;border-style:solid;border-color:var(--gs-border,#e3e6ea);border-width:var(--gs-fb-bt,1px) var(--gs-fb-br,1px) var(--gs-fb-bb,1px) var(--gs-fb-bl,1px);padding:3px 6px;gap:6px}.gs-formula-bar .gs-selecting-address{display:flex;align-items:center;justify-content:center;min-width:38px;padding:0 4px;color:var(--gs-muted-fg,#6b7280);font-size:12px;font-variant-numeric:tabular-nums;text-align:center}.gs-formula-bar[data-spill=true]{background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 6%,var(--gs-header-bg,#f4f5f7))}.gs-formula-bar[data-spill=true] .gs-selecting-address{color:var(--gs-accent,#2563eb);font-style:italic}.gs-formula-bar[data-spill=true] .gs-selecting-address::after{content:"\\2196";margin-left:2px;font-style:normal;font-size:9px}.gs-formula-bar .gs-fx{display:flex;align-items:center;justify-content:center;align-self:center;width:26px;height:18px;flex-shrink:0;color:var(--gs-muted-fg,#6b7280);font-style:italic;font-family:inherit;font-weight:400;text-align:center;font-size:13px;letter-spacing:.3px;border-radius:4px;background-color:color-mix(in srgb,var(--gs-fg,#1f2328) 6%,transparent)}.gs-formula-bar .gs-editor-hl{z-index:0;overflow-y:auto;box-sizing:border-box;white-space:pre-wrap;word-break:break-all;text-align:left;line-height:24px}.gs-formula-bar textarea{position:relative;z-index:1;width:100%;vertical-align:bottom;color:transparent;border:none;background-color:transparent;padding:0 2px;box-sizing:border-box;text-align:left;outline:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;font-size:12px;font-family:monospace,Arial;height:24px;line-height:24px;min-height:24px;letter-spacing:1px;resize:vertical;caret-color:var(--gs-fg,#1f2328);white-space:pre-wrap;word-break:break-all}.gs-token-type-INVALID_REF{color:red}.gs-token-type-VALUE.gs-token-entity-type-boolean,.gs-token-type-VALUE.gs-token-entity-type-number{color:#39f}.gs-token-type-VALUE.gs-token-entity-type-string{color:#090}.gs-editor-options{position:fixed;z-index:1000;padding:4px;background:var(--gs-bg,#fff);box-shadow:0 4px 12px rgba(0,0,0,.15);border:1px solid rgba(0,0,0,.1);border-radius:6px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;overflow:visible}.gs-editor-option{position:relative;cursor:pointer;list-style:none;padding:6px 12px;font-size:13px;border-radius:4px;color:#333;margin-bottom:2px}.gs-editor-option-content{display:flex;justify-content:space-between;width:100%;align-items:center}.gs-editor-option-tab{font-size:10px;color:#aaa;margin-left:8px;padding:2px 4px;border:1px solid #ddd;border-radius:3px;background:#f9f9f9}.gs-editor-option:last-child{margin-bottom:0}.gs-editor-option:hover{background-color:#f5f5f5}.gs-editor-option-selected{background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);color:var(--gs-accent,#2563eb);font-weight:500}.gs-editor-option-selected:hover{background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 18%,transparent)}.gs-fn-guide1{position:absolute;top:-4px;left:calc(100% + 8px);background:#fff;border:1px solid rgba(0,0,0,.1);box-shadow:0 4px 16px rgba(0,0,0,.12);border-radius:6px;padding:16px;width:280px;z-index:1000;cursor:default;white-space:normal;color:#333}.gs-fn-guide1-tooltip{margin-bottom:8px;line-height:1.4;font-size:13px}.gs-fn-guide1-example{font-family:monospace;font-weight:600;font-size:13px;margin-bottom:8px;color:#1a1a1a;background:#f5f5f5;padding:6px 8px;border-radius:4px;border:1px solid #eee;display:flex;align-items:center;gap:6px;flex-wrap:wrap}.gs-fn-guide1-desc{font-size:13px;color:#555;margin-bottom:12px;line-height:1.4}.gs-fn-guide1-desc p{margin:0 0 6px 0}.gs-fn-guide1-desc p:last-child{margin-bottom:0}.gs-fn-guide1-args{border-top:1px solid #eee;padding-top:10px}.gs-fn-guide1-arg{margin-bottom:6px;line-height:1.4;font-size:12px}.gs-fn-guide1-arg-name{font-weight:600;color:var(--gs-accent,#2563eb)}.gs-fn-guide1-arg-opt{color:#888;font-size:11px}.gs-fn-guide1-arg-iter{font-weight:600;color:var(--gs-accent,#2563eb)}.gs-fn-guide1-arg-type{color:var(--gs-accent,#2563eb);padding:0 4px;background:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);border-radius:3px;font-size:11px;margin:0 4px}.gs-fn-guide1-arg-desc{color:#666}.gs-fn-guide-category{position:absolute;top:-11px;right:8px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;font-size:11px;font-weight:600;letter-spacing:.5px;text-transform:uppercase;padding:2px 7px;border-radius:4px;background:#e8eaf6;color:#3949ab;border:1px solid #c5cae9;white-space:nowrap}.gs-fn-guide-category.gs-fn-guide-category-math{background:#e3f2fd;color:#1565c0;border-color:#bbdefb}.gs-fn-guide-category.gs-fn-guide-category-statistics{background:#e8f5e9;color:#2e7d32;border-color:#c8e6c9}.gs-fn-guide-category.gs-fn-guide-category-text{background:#fff8e1;color:#f57f17;border-color:#ffecb3}.gs-fn-guide-category.gs-fn-guide-category-time{background:#fce4ec;color:#880e4f;border-color:#f8bbd0}.gs-fn-guide-category.gs-fn-guide-category-lookup{background:#f3e5f5;color:#6a1b9a;border-color:#e1bee7}.gs-fn-guide-category.gs-fn-guide-category-logical{background:#e0f2f1;color:#00695c;border-color:#b2dfdb}.gs-fn-guide-category.gs-fn-guide-category-information{background:#e0f7fa;color:#006064;border-color:#b2ebf2}.gs-fn-guide-category.gs-fn-guide-category-finance{background:#fff3e0;color:#e65100;border-color:#ffe0b2}.gs-fn-guide-category.gs-fn-guide-category-engineering{background:#efebe9;color:#4e342e;border-color:#d7ccc8}.gs-fn-guide-category.gs-fn-guide-category-ai{background:#e8eaf6;color:#3949ab;border-color:#c5cae9}.gs-fn-guide-category.gs-fn-guide-category-other{background:#f5f5f5;color:#616161;border-color:#e0e0e0}.gs-editor-portal{display:contents}.gs-editor-portal[data-mode=dark] .gs-editor-options,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-options,.gs-editor[data-mode=dark] .gs-editor-options,.gs-editor[data-mode=inherit-dark] .gs-editor-options{background:#252526;border-color:#454545;box-shadow:0 4px 12px rgba(0,0,0,.5)}.gs-editor-portal[data-mode=dark] .gs-editor-option,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option,.gs-editor[data-mode=dark] .gs-editor-option,.gs-editor[data-mode=inherit-dark] .gs-editor-option{color:#ccc}.gs-editor-portal[data-mode=dark] .gs-editor-option:hover,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option:hover,.gs-editor[data-mode=dark] .gs-editor-option:hover,.gs-editor[data-mode=inherit-dark] .gs-editor-option:hover{background-color:#333}.gs-editor-portal[data-mode=dark] .gs-editor-option-selected,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option-selected,.gs-editor[data-mode=dark] .gs-editor-option-selected,.gs-editor[data-mode=inherit-dark] .gs-editor-option-selected{background-color:#094771;color:#fff}.gs-editor-portal[data-mode=dark] .gs-editor-option-selected:hover,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option-selected:hover,.gs-editor[data-mode=dark] .gs-editor-option-selected:hover,.gs-editor[data-mode=inherit-dark] .gs-editor-option-selected:hover{background-color:#0d5a8f}.gs-editor-portal[data-mode=dark] .gs-editor-option-tab,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option-tab,.gs-editor[data-mode=dark] .gs-editor-option-tab,.gs-editor[data-mode=inherit-dark] .gs-editor-option-tab{color:#777;background:#333;border-color:#444}.gs-editor-portal[data-mode=dark] .gs-fn-guide1,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1,.gs-editor[data-mode=dark] .gs-fn-guide1,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1{background:#252526;border-color:#454545;color:#ccc}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-example,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-example,.gs-editor[data-mode=dark] .gs-fn-guide1-example,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-example{background:#1e1e1e;border-color:#333;color:#d4d4d4}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-desc,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-desc,.gs-editor[data-mode=dark] .gs-fn-guide1-desc,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-desc{color:#aaa}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-args,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-args,.gs-editor[data-mode=dark] .gs-fn-guide1-args,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-args{border-color:#333}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-iter,.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-name,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-iter,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-name,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-iter,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-name,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-iter,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-name{color:#4fc1ff}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-opt,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-opt,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-opt,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-opt{color:#777}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-type,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-type,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-type,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-type{background:#094771;color:#4fc1ff}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-desc,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-desc,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-desc,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-desc{color:#999}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category,.gs-editor[data-mode=dark] .gs-fn-guide-category,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category{background:#2a2d3e;color:#7986cb;border-color:#3d4166}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-math,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-math,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-math,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-math{background:#0d2137;color:#64b5f6;border-color:#1a3a5c}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-statistics,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-statistics,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-statistics,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-statistics{background:#0d2218;color:#66bb6a;border-color:#1a3d2a}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-text,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-text,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-text,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-text{background:#2e2200;color:#ffd54f;border-color:#4d3900}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-time,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-time,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-time,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-time{background:#2d0d1e;color:#f48fb1;border-color:#4d1a33}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-lookup,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-lookup,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-lookup,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-lookup{background:#260d33;color:#ce93d8;border-color:#3d1a54}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-logical,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-logical,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-logical,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-logical{background:#0d2421;color:#4db6ac;border-color:#1a3d39}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-information,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-information,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-information,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-information{background:#0d2426;color:#4dd0e1;border-color:#1a3d40}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-finance,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-finance,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-finance,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-finance{background:#2e1500;color:#ffb74d;border-color:#4d2800}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-engineering,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-engineering,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-engineering,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-engineering{background:#1e1714;color:#bcaaa4;border-color:#332c28}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-ai,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-ai,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-ai,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-ai{background:#10142e;color:#7986cb;border-color:#232a52}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-other,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-other,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-other,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-other{background:#1e1e1e;color:#9e9e9e;border-color:#333}.gs-editor-portal[data-mode=dark] .gs-fn-guide2,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2,.gs-editor[data-mode=dark] .gs-fn-guide2,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2{background:#252526;border-color:#454545;box-shadow:0 4px 12px rgba(0,0,0,.5);color:#ccc}.gs-editor-portal[data-mode=dark] .gs-fn-guide2-name,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2-name,.gs-editor[data-mode=dark] .gs-fn-guide2-name,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2-name{color:#dfdbdb;background:#333;border-color:#444}.gs-editor-portal[data-mode=dark] .gs-fn-guide2 .gs-active-arg,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2 .gs-active-arg,.gs-editor[data-mode=dark] .gs-fn-guide2 .gs-active-arg,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2 .gs-active-arg{color:#fff;background-color:#094771}.gs-editor-portal[data-mode=dark] .gs-fn-guide2-arg-type,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2-arg-type,.gs-editor[data-mode=dark] .gs-fn-guide2-arg-type,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2-arg-type{background:#094771;color:#4fc1ff}.gs-editor-portal[data-mode=dark] .gs-fn-guide2-desc,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2-desc,.gs-editor[data-mode=dark] .gs-fn-guide2-desc,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2-desc{color:#aaa;border-top-color:#333}.gs-fn-guide2{position:fixed;left:0;background:#fff;border:1px solid rgba(0,0,0,.1);box-shadow:0 4px 16px rgba(0,0,0,.12);border-radius:6px;padding:12px 16px;width:280px;z-index:1000;cursor:default;white-space:normal;color:#333;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;transition:opacity .1s ease-in-out}.gs-fn-guide2.gs-fn-guide2-hidden{opacity:0!important;pointer-events:none!important}.gs-fn-guide2-name{font-family:monospace;font-weight:700;font-size:13px;color:#1a1a1a;background:#f5f5f5;padding:6px 8px;border-radius:4px;border:1px solid #eee;display:flex;align-items:center;gap:6px;flex-wrap:wrap;width:100%;box-sizing:border-box;margin-bottom:8px}.gs-fn-guide2-args-inline{font-size:13px;font-family:monospace;line-height:1.5;margin-bottom:8px;color:#666}.gs-fn-guide2-args-inline span{transition:all .2s ease-in-out}.gs-fn-guide2 .gs-active-arg{font-weight:700;color:var(--gs-accent,#2563eb);background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);padding:2px 4px;margin:0 -4px;border-radius:4px}.gs-fn-guide2-arg-type{color:var(--gs-accent,#2563eb);padding:0 4px;background:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);border-radius:3px;font-size:11px;margin:0 4px}.gs-fn-guide2-desc{font-size:12px;color:#555;line-height:1.4;border-top:1px solid #eee;padding-top:8px;margin-top:4px}.gs-fn-guide2-desc p{margin:0}.gs-fn-guide2-desc-more{font-style:italic;color:#888;margin-top:4px!important;font-size:11px}.gs-adjuster{padding:0}.gs-table{margin:0}.gs-tabular{overflow:auto;overflow-anchor:none;display:flex;box-sizing:border-box;position:relative}.gs-root1[data-matrix-align=both] .gs-tabular,.gs-root1[data-matrix-align=horizontal] .gs-tabular{justify-content:safe center}.gs-root1[data-matrix-align=both] .gs-tabular,.gs-root1[data-matrix-align=vertical] .gs-tabular{align-items:safe center}.gs-tabular-inner{flex:0 0 auto;position:relative;overflow:hidden;overflow:clip;box-sizing:border-box;border-right:solid var(--gs-mx-br,1px) var(--gs-border,#e3e6ea);border-bottom:solid var(--gs-mx-bb,1px) var(--gs-border,#e3e6ea)}.gs-tabular-inner>table{table-layout:fixed;border-collapse:collapse;border-spacing:0}.gs-ghost-layer{font-size:13px}.gs-ghost-layer .gs-ghost-panel{position:fixed;overflow:hidden;z-index:1000;cursor:crosshair}.gs-ghost-layer .gs-ghost-cell,.gs-ghost-layer .gs-ghost-th{position:absolute;box-sizing:border-box}.gs-ghost-layer .gs-ghost-cell{border:dashed 1px var(--gs-border,#e3e6ea);background-color:color-mix(in srgb,var(--gs-surface,#fff) 70%,transparent)}.gs-ghost-layer .gs-ghost-cell.gs-ghost-target{background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,var(--gs-surface,#fff));border-color:color-mix(in srgb,var(--gs-accent,#2563eb) 45%,transparent)}.gs-ghost-layer .gs-ghost-th{display:flex;align-items:center;justify-content:center;background-color:var(--gs-header-bg,#f6f7f9);color:var(--gs-header-fg,#555);border:dashed 1px var(--gs-border,#e3e6ea);opacity:.75}.gs-main[data-overflow-x=true] .gs-tabular-inner{border-right-width:0}.gs-main[data-overflow-y=true] .gs-tabular-inner{border-bottom-width:0}.gs-main::after{content:'';position:absolute;inset:0;pointer-events:none;z-index:3;border:0 solid var(--gs-border,#e3e6ea)}.gs-main[data-overflow-x=true]::after{border-right-width:var(--gs-mx-br,1px)}.gs-main[data-overflow-y=true]::after{border-bottom-width:var(--gs-mx-bb,1px)}.gs-th{z-index:2;padding:0;position:sticky;font-size:13px;font-weight:400;box-sizing:border-box;vertical-align:top}.gs-th .gs-resizer{position:absolute;border-color:transparent;box-sizing:border-box;z-index:2}.gs-th .gs-resizer:hover{background-color:var(--gs-accent,#2563eb)}.gs-th .gs-resizer.gs-protected{display:none}.gs-th-inner{height:100%;box-sizing:border-box;vertical-align:middle;overflow:hidden;display:flex;align-items:center;justify-content:center}.gs-th-inner-wrap{height:100%;box-sizing:border-box;background-color:transparent}.gs-th-top{top:0;overflow:hidden}.gs-th-top .gs-resizer{top:0;right:0;width:3px;cursor:e-resize}.gs-th-top .gs-resizer.gs-dragging{border-right-style:dotted;height:1000000px!important;cursor:e-resize}.gs-th-left{left:0;overflow:hidden;min-width:30px;border-top:solid 1px var(--gs-border,#e3e6ea)}.gs-th-left .gs-resizer{left:0;bottom:0;height:3px;cursor:n-resize}.gs-th-left .gs-resizer.gs-dragging{border-bottom-style:dotted;width:1000000px!important;cursor:n-resize}.gs-th-top.gs-th-left{top:0;left:0;z-index:3;border:none!important}.gs-th-left.gs-filter-fixed .gs-th-inner::before{content:'‹\\00a0'}.gs-th-left.gs-sort-fixed .gs-th-inner::after{content:'\\00a0›'}.gs-col-addr{position:absolute;top:2px;right:4px;font-size:9px;opacity:.5;line-height:1;letter-spacing:.3px;pointer-events:none}.gs-search-bar{width:100%;display:flex;align-items:center;padding:3px 0;border-top:solid 1px rgba(128,128,128,.3);border-left:solid 1px rgba(128,128,128,.3);border-right:solid 1px rgba(128,128,128,.3);border-bottom:solid 1px rgba(128,128,128,.3);box-sizing:border-box;background-color:rgba(200,50,0,.2)}.gs-search-bar.gs-search-found{background-color:rgba(0,200,100,.2)}.gs-search-bar .gs-search-bar-inner{border-left:solid 1px rgba(128,128,128,.5)}.gs-search-bar .gs-search-bar-icon{border-left:solid 1px rgba(128,128,128,.3);display:flex;align-items:center;justify-content:center;width:30px;flex-shrink:0}.gs-search-bar .gs-search-input-wrapper{flex-grow:1;position:relative;display:flex;align-items:center;height:100%}.gs-search-bar .gs-search-input-ghost{position:absolute;left:2px;right:2px;top:0;bottom:0;pointer-events:none;font-size:12px;font-family:monospace,Arial;line-height:24px;letter-spacing:1px;white-space:pre-wrap;word-break:break-all;color:transparent;overflow:hidden}.gs-search-bar .gs-search-input-ghost .gs-search-ghost-hint{color:#aaa}.gs-search-bar textarea{background-color:transparent;border:none;padding:0 2px;box-sizing:border-box;outline:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;font-size:12px;font-family:monospace,Arial;height:24px;line-height:24px;min-height:24px;letter-spacing:1px;caret-color:rgba(128,128,128);white-space:pre-wrap;word-break:break-all;flex-grow:1;width:100%;resize:none}.gs-search-progress{color:#999;font-size:13px;width:60px;flex-shrink:0;white-space:nowrap;text-align:center}.gs-search-close{cursor:pointer;display:flex;align-items:center;justify-content:center;width:24px;flex-shrink:0}.gs-search-buttons{display:flex;align-items:center;white-space:nowrap;flex-shrink:0}.gs-search-button{display:inline-flex;cursor:pointer;margin:0 2px}.gs-search-button span{display:inline-block;font-size:11px;padding:3px 5px;background-color:rgba(128,128,128,.1);border:1px solid rgba(128,128,128,.3);border-radius:3px;transition:all .15s ease;line-height:1}.gs-search-button span:hover{background-color:rgba(128,128,128,.2)}.gs-search-button span.gs-search-button-on{color:var(--gs-accent,#2563eb);background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 22%,transparent);border-color:var(--gs-accent,#2563eb)}.gs-search-range span{white-space:nowrap;font-family:monospace}@keyframes spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}.gs-loading-overlay{position:absolute;top:0;left:0;right:0;bottom:0;background:color-mix(in srgb,var(--gs-surface,#fff) 70%,transparent);display:flex;align-items:center;justify-content:center;z-index:100;pointer-events:all}.gs-loading-spinner{width:32px;height:32px;border:3px solid color-mix(in srgb,var(--gs-fg,#1f2328) 12%,transparent);border-top-color:var(--gs-accent,#2563eb);border-radius:50%;animation:spin .8s linear infinite}.gs-progress-overlay{position:absolute;top:0;left:0;right:0;bottom:0;z-index:100;pointer-events:all;display:flex;align-items:center;justify-content:center}.gs-progress-box{min-width:240px;padding:16px 18px;border-radius:8px;background:var(--gs-editor-surface,#fff);border:1px solid var(--gs-border,#e3e6ea);box-shadow:0 6px 24px rgba(0,0,0,.28);display:flex;flex-direction:column;gap:10px}.gs-progress-head{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--gs-fg,#1f2328)}.gs-progress-head .gs-loading-spinner{width:15px;height:15px;border-width:2px}.gs-progress-track{height:6px;border-radius:3px;overflow:hidden;background:color-mix(in srgb,var(--gs-fg,#1f2328) 12%,transparent)}.gs-progress-fill{height:100%;border-radius:3px;background:var(--gs-accent,#2563eb);transition:width .1s linear}@keyframes gs-pending-slide{0%{left:-40%}100%{left:100%}}@keyframes gs-pending-pulse{0%{left:0;width:0}50%{left:0;width:100%}100%{left:100%;width:0}}@keyframes gs-flash{0%{opacity:0}20%{opacity:1}100%{opacity:0}}.gs-flash-overlay{position:absolute;inset:0;pointer-events:none;z-index:9999;background:color-mix(in srgb,var(--gs-accent,#2563eb) 15%,transparent);opacity:0}.gs-flash-overlay--active{animation:gs-flash .6s ease-out forwards}`; diff --git a/packages/web/src/styles/root.min.css b/packages/web/src/styles/root.min.css index 6e6e0901..a6ec67e3 100644 --- a/packages/web/src/styles/root.min.css +++ b/packages/web/src/styles/root.min.css @@ -1 +1 @@ -.gs-root1{display:inline-block;position:relative;border-spacing:0;width:fit-content;max-width:100%;overflow:auto;font-family:"SF Pro Text","SF Pro Icons","Helvetica Neue",Helvetica,Arial,Meiryo,sans-serif;visibility:hidden;opacity:0}.gs-root1.gs-initialized{visibility:visible;opacity:1;transition:opacity .2s ease-in-out}.gs-root1 .gs-main{flex:1;max-width:100%;overflow:hidden;position:relative;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box}.gs-root1 .gs-resizing{width:100%;height:100%;position:absolute;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 8%,transparent);top:0;left:0;z-index:2}.gs-root1 .gs-line-horizontal{width:100%}.gs-root1 .gs-line-vertical{height:100%}.gs-root1 .gs-line{position:relative;top:0;left:0;border:dotted 1px var(--gs-accent,#2563eb);box-sizing:border-box}.gs-root1 .gs-line span{font-size:10px;padding:3px;background-color:var(--gs-accent,#2563eb);color:#fff;margin:0;position:absolute;top:0;left:0}.gs-root1 .gs-scroll-handle{width:100%;height:100%;cursor:cell}.gs-hidden{visibility:hidden;position:absolute;top:0;left:0;width:0;height:0;overflow:hidden;pointer-events:none;z-index:-1}.gs-fixed{position:fixed;top:0;left:0;z-index:1}:where(.gs-root1[data-mode=light],.gs-editor[data-mode=light]){--gs-fg:#1f2328;--gs-muted-fg:#6b7280;--gs-border:#e3e6ea;--gs-bg:rgba(128, 128, 128, 0.07);--gs-canvas:transparent;--gs-surface:#ffffff;--gs-editor-surface:#ffffff;--gs-header-bg:#f4f5f7;--gs-header-fg:#59616b;--gs-accent:#2563eb}.gs-root1{background-color:var(--gs-bg);color:var(--gs-fg)}.gs-root1 .gs-main{background-color:var(--gs-canvas)}.gs-root1 .gs-tabular{background-color:var(--gs-canvas)}.gs-root1 .gs-sheet-body-data{background-color:var(--gs-surface)}.gs-root1 .gs-formula-bar{background-color:var(--gs-header-bg)}.gs-root1 .gs-formula-bar-editor-inner{color:var(--gs-fg)}.gs-root1 .gs-cell{border:solid 1px var(--gs-border)}.gs-root1 .gs-adjuster{background-color:var(--gs-border)}.gs-root1 .gs-tabular-inner{background-color:var(--gs-border)}.gs-root1 .gs-large-editor textarea{color:var(--gs-fg);caret-color:var(--gs-fg)}.gs-root1 .gs-th{background-color:var(--gs-header-bg);color:var(--gs-header-fg)}.gs-root1 .gs-th-top{border-left:solid 1px var(--gs-border)}.gs-root1 .gs-th-top .gs-th-inner{border-top:solid var(--gs-mx-bt,1px) var(--gs-border)}.gs-root1 .gs-th-left{border-top:solid 1px var(--gs-border)}.gs-root1 .gs-th-left .gs-th-inner{border-left:solid var(--gs-mx-bl,1px) var(--gs-border)}.gs-root1 .gs-search-bar{color:color-mix(in srgb,var(--gs-fg) 40%,transparent)}.gs-root1 .gs-search-bar textarea{color:var(--gs-fg);caret-color:var(--gs-fg)}.gs-editor.gs-editing textarea{caret-color:var(--gs-fg)}.gs-editor.gs-editing .gs-editor-hl{background-color:var(--gs-editor-surface);color:var(--gs-fg)}.gs-editor .gs-editor-options{color:var(--gs-fg);background-color:var(--gs-editor-surface);border:solid 1px var(--gs-border)}:where(.gs-root1[data-mode=dark],.gs-editor[data-mode=dark]){--gs-fg:#e4e6e9;--gs-muted-fg:#8b9096;--gs-border:#2c2f34;--gs-bg:rgba(128, 128, 128, 0.07);--gs-canvas:transparent;--gs-surface:#1c1e21;--gs-editor-surface:#1c1e21;--gs-header-bg:#212327;--gs-header-fg:#a6abb2;--gs-accent:#3b82f6}:where(.gs-root1[data-mode=auto],.gs-editor[data-mode=auto]){--gs-fg:#1f2328;--gs-muted-fg:#6b7280;--gs-border:#e3e6ea;--gs-bg:rgba(128, 128, 128, 0.07);--gs-canvas:transparent;--gs-surface:#ffffff;--gs-editor-surface:#ffffff;--gs-header-bg:#f4f5f7;--gs-header-fg:#59616b;--gs-accent:#2563eb}@media (prefers-color-scheme:dark){:where(.gs-root1[data-mode=auto],.gs-editor[data-mode=auto]){--gs-fg:#e4e6e9;--gs-muted-fg:#8b9096;--gs-border:#2c2f34;--gs-bg:rgba(128, 128, 128, 0.07);--gs-canvas:transparent;--gs-surface:#1c1e21;--gs-editor-surface:#1c1e21;--gs-header-bg:#212327;--gs-header-fg:#a6abb2;--gs-accent:#3b82f6}}:where(.gs-root1[data-mode=inherit-light],.gs-editor[data-mode=inherit-light]){--gs-fg:#1f2328;--gs-muted-fg:#6b7280;--gs-border:#e3e6ea;--gs-bg:rgba(128, 128, 128, 0.07);--gs-surface:#ffffff;--gs-editor-surface:#ffffff;--gs-header-bg:#f4f5f7;--gs-header-fg:#59616b;--gs-accent:#2563eb;--gs-bg:transparent;--gs-canvas:transparent;--gs-surface:transparent;--gs-header-bg:transparent}:where(.gs-root1[data-mode=inherit-dark],.gs-editor[data-mode=inherit-dark]){--gs-fg:#e4e6e9;--gs-muted-fg:#8b9096;--gs-border:#2c2f34;--gs-bg:rgba(128, 128, 128, 0.07);--gs-surface:#1c1e21;--gs-editor-surface:#1c1e21;--gs-header-bg:#212327;--gs-header-fg:#a6abb2;--gs-accent:#3b82f6;--gs-bg:transparent;--gs-canvas:transparent;--gs-surface:transparent;--gs-header-bg:transparent}.gs-root1[data-mode=inherit-dark] .gs-adjuster,.gs-root1[data-mode=inherit-dark] .gs-tabular-inner,.gs-root1[data-mode=inherit-light] .gs-adjuster,.gs-root1[data-mode=inherit-light] .gs-tabular-inner{background-color:transparent}.gs-root1[data-mode=inherit-light] .gs-th{background-color:rgba(128,128,128,.1);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}.gs-root1[data-mode=inherit-dark] .gs-th{background-color:rgba(128,128,128,.1);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}.gs-root1[data-gridlines=horizontal] .gs-cell{border-left-color:transparent;border-right-color:transparent}.gs-root1[data-gridlines=none] .gs-cell{border-color:transparent}.gs-root1[data-density=comfortable] .gs-cell-rendered{padding:0 10px}.gs-cell{transition:border-color .2s ease;padding:0;margin:0;box-sizing:border-box;position:relative;font-size:13px;letter-spacing:1px;line-height:24px;cursor:cell;user-select:none;-webkit-user-select:none;-moz-user-select:none}.gs-cell.gs-copying textarea:focus{outline:solid 1px var(--gs-accent,#2563eb)}.gs-cell.gs-selecting{z-index:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 7%,transparent)}.gs-cell.gs-selecting .gs-cell-label{display:block}.gs-cell.gs-choosing{margin-top:-1px;margin-left:-1px;z-index:1}.gs-cell.gs-choosing.gs-editing{color:transparent}.gs-cell.gs-choosing .gs-cell-label{display:block}.gs-cell.gs-pending .gs-cell-rendered{position:relative;overflow:hidden}.gs-cell.gs-pending .gs-cell-rendered::after{content:'';position:absolute;bottom:0;left:0;height:4px;width:40%;border-radius:1px;background:color-mix(in srgb,var(--gs-accent,#2563eb) 65%,transparent);animation:gs-pending-slide 1.4s ease-in-out infinite}.gs-cell .gs-formula-error-triangle{position:absolute;top:0;right:0;border-top:4px solid rgba(200,0,0,.9);border-right:4px solid rgba(200,0,0,.9);border-bottom:4px solid transparent;border-left:4px solid transparent;z-index:2;cursor:help}.gs-cell .gs-cell-label{font-size:10px;font-weight:500;font-style:normal;font-family:inherit;letter-spacing:.2px;line-height:1.4;position:absolute;top:0;right:0;background-color:var(--gs-accent,#2563eb);color:#fff;padding:1px 5px;border-bottom-left-radius:4px;display:none;opacity:.92}.gs-cell .gs-cell-inner-wrap{width:100%;height:100%;position:absolute;top:0;left:0}.gs-cell .gs-cell-inner{width:100%;height:100%;overflow:hidden;display:flex;box-sizing:border-box;border:none!important}.gs-cell .gs-cell-rendered{overflow:hidden;white-space:pre-wrap;cursor:cell;word-wrap:break-word;word-break:break-all;padding:0 6px;width:100%;height:100%}.gs-cell .gs-cell-rendered>*{position:relative}.gs-cell .gs-cell-rendered>.backface{z-index:0}.gs-cell .gs-autofill-drag{background-color:var(--gs-accent,#2563eb);position:absolute;width:7px;height:7px;bottom:0;right:0;cursor:crosshair;z-index:1}.gs-cell.gs-merged-host{z-index:1}.gs-cell.gs-merged-host.gs-selecting{background-color:transparent}.gs-cell.gs-merged-host.gs-selecting .gs-cell-inner-wrap{background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 7%,transparent)}.gs-cell.gs-merged-covered{z-index:0}.gs-th[data-x="1"] .gs-th-inner-wrap{border-left:none}.gs-th[data-y="1"] .gs-th-inner-wrap{border-top:none}.gs-formula-error-tooltip{position:fixed;background-color:rgba(35,8,8,.94);color:#fff;padding:6px 10px;border-radius:4px;border-left:3px solid rgba(220,50,50,.8);font-size:12px;line-height:1.5;max-width:260px;white-space:pre-wrap;word-break:break-word;box-shadow:0 3px 10px rgba(0,0,0,.4);z-index:100;pointer-events:none;letter-spacing:.3px}.gs-menu-modal{width:100%;height:100vh;z-index:12}.gs-label-input-label{font-size:13px;letter-spacing:1px}.gs-menu-divider{background-color:#aaa;padding:0;margin:5px 0;height:1px;list-style-type:none}.gs-menu-btn{position:absolute;background-color:rgba(128,128,128,.3);border:1px solid #ccc;border-radius:50%;cursor:pointer;font-size:12px;font-weight:700;line-height:1;color:#888;width:18px;height:18px;padding:0;display:flex;align-items:center;justify-content:center;opacity:0;transition:opacity .15s ease;z-index:2}.gs-context-menu{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;opacity:.9;transition:opacity .15s ease}.gs-context-menu:hover{opacity:1}.gs-context-menu .gs-menu-items{color:#555;margin:0;padding:0;min-width:250px}.gs-menu-item{padding:5px 10px;list-style-type:none;display:flex}.gs-menu-item.gs-enabled{cursor:pointer}.gs-menu-item.gs-enabled:hover{background-color:#eee}.gs-menu-item.gs-disabled{opacity:.5;cursor:not-allowed}.gs-menu-item .gs-menu-name{font-size:13px;letter-spacing:1px;flex:1}.gs-submenu-parent{position:relative;align-items:center}.gs-submenu-parent .gs-submenu-arrow{margin-left:8px;font-size:11px;opacity:.6}.gs-submenu-flyout{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;opacity:.9;transition:opacity .15s ease;min-width:200px;margin:0;color:#555;opacity:1;list-style-type:none}.gs-submenu-flyout:hover{opacity:1}.gs-menu-shortcut{font-size:10px;line-height:20px;color:#999}.gs-menu-shortcut:before{content:"( "}.gs-menu-shortcut:after{content:" )"}.gs-menu-shortcut .gs-menu-underline{text-decoration:underline}.gs-column-menu{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;opacity:.9;transition:opacity .15s ease}.gs-column-menu:hover{opacity:1}.gs-column-menu ul{color:#555;margin:0;padding:0;min-width:200px}.gs-column-menu .gs-column-menu-sort{align-items:center}.gs-column-menu .gs-column-menu-sort .gs-sort-buttons{display:flex;gap:4px;margin-left:auto}.gs-column-menu .gs-column-menu-sort .gs-sort-btn{font-size:12px;padding:4px 8px;border:1px solid transparent;border-radius:3px;background-color:rgba(180,180,180,.1);cursor:pointer;color:#555;font-weight:700;letter-spacing:.5px}.gs-column-menu .gs-column-menu-sort .gs-sort-btn:hover:not(:disabled){border-color:#555}.gs-column-menu .gs-column-menu-sort .gs-sort-btn:disabled{opacity:.5;cursor:not-allowed}.gs-column-menu .gs-column-menu-label{padding:5px 10px}.gs-column-menu .gs-label-input-row{display:flex;gap:4px;align-items:center}.gs-column-menu .gs-label-input{flex:1;font-size:13px;padding:4px 6px;border:none;border-bottom:1px solid #ccc;border-radius:0;outline:0;min-width:0;width:100px;background-color:transparent;box-shadow:none}.gs-column-menu .gs-label-input:focus{border-bottom-color:var(--gs-accent,#2563eb);outline:0;box-shadow:none}.gs-column-menu .gs-label-apply-btn{font-size:12px;padding:4px 8px;border:1px solid transparent;border-radius:3px;background-color:rgba(180,180,180,.1);cursor:pointer;color:#555;font-weight:700;letter-spacing:.5px}.gs-column-menu .gs-label-apply-btn:hover:not(:disabled){border-color:#555}.gs-column-menu .gs-label-apply-btn:disabled{opacity:.5;cursor:not-allowed}.gs-column-menu .gs-column-menu-filter{padding:5px 10px;list-style-type:none;font-size:13px}.gs-column-menu .gs-filter-header{display:flex;align-items:center;gap:8px}.gs-column-menu .gs-filter-header .gs-filter-add-btn{font-size:12px;padding:3px 9px;border:1px solid transparent;border-radius:3px;background-color:rgba(180,180,180,.1);cursor:pointer;color:#555;letter-spacing:1px}.gs-column-menu .gs-filter-header .gs-filter-add-btn:hover{border-color:#555}.gs-column-menu .gs-filter-mode-toggle{display:flex;gap:6px;margin-left:auto}.gs-column-menu .gs-filter-mode-toggle label{display:flex;align-items:center;gap:3px;font-size:11px;font-weight:700;letter-spacing:.5px;color:#888;cursor:pointer;user-select:none}.gs-column-menu .gs-filter-mode-toggle label input[type=radio]{margin:0;cursor:pointer}.gs-column-menu .gs-filter-mode-toggle label.gs-active{color:var(--gs-accent,#2563eb)}.gs-column-menu .gs-filter-mode-toggle.gs-disabled{opacity:.4;pointer-events:none}.gs-column-menu .gs-filter-conditions{display:flex;flex-direction:column;gap:5px;margin-top:6px;max-height:200px;overflow-y:auto}.gs-column-menu .gs-filter-condition-row{display:flex;gap:4px;align-items:normal}.gs-column-menu .gs-filter-method-select{font-size:12px;padding:4px 4px;border:none;border-bottom:1px solid #ccc;border-radius:0;outline:0;background-color:#fff;box-shadow:none;min-width:40px;max-width:80px;cursor:pointer}.gs-column-menu .gs-filter-method-select:focus{border-bottom-color:var(--gs-accent,#2563eb);outline:0;box-shadow:none}.gs-column-menu .gs-filter-value-input{flex:1;font-size:13px;padding:4px 6px;border:none;border-bottom:1px solid #ccc;border-radius:0;outline:0;min-width:0;width:80px;background-color:transparent;box-shadow:none}.gs-column-menu .gs-filter-value-input:focus{border-bottom-color:var(--gs-accent,#2563eb);outline:0;box-shadow:none}.gs-column-menu .gs-filter-remove-btn{font-size:12px;padding:0;border:none;border-radius:3px;background-color:transparent;cursor:pointer;color:#999;line-height:1;flex-shrink:0}.gs-column-menu .gs-filter-remove-btn:hover{color:#c33}.gs-column-menu .gs-filter-actions{display:flex;gap:4px;margin-top:10px;align-items:center}.gs-column-menu .gs-filter-actions .gs-filter-reset-all-btn{font-size:12px;padding:3px 9px;border:1px solid transparent;border-radius:3px;background-color:transparent;cursor:pointer;color:#c33;font-weight:700;letter-spacing:1px}.gs-column-menu .gs-filter-actions .gs-filter-reset-all-btn:hover{border-color:#c33}.gs-column-menu .gs-filter-actions .gs-filter-actions-right{display:flex;gap:4px;margin-left:auto}.gs-column-menu .gs-filter-actions .gs-filter-reset-btn{font-size:12px;padding:3px 9px;border:1px solid transparent;border-radius:3px;background-color:transparent;cursor:pointer;color:#e08000;font-weight:700;letter-spacing:1px}.gs-column-menu .gs-filter-actions .gs-filter-reset-btn:hover{border-color:#e08000}.gs-column-menu .gs-filter-actions .gs-filter-apply-btn{font-size:12px;padding:3px 6px;border:1px solid transparent;border-radius:3px;background-color:transparent;color:var(--gs-accent,#2563eb);cursor:pointer;font-weight:700;letter-spacing:1px}.gs-column-menu .gs-filter-actions .gs-filter-apply-btn:hover{border-color:var(--gs-accent,#2563eb)}.gs-column-menu-waiting{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:20px 30px;gap:12px;min-width:180px}.gs-column-menu-waiting .gs-waiting-message{font-size:13px;font-weight:700;color:#555;letter-spacing:.5px}.gs-column-menu-waiting .gs-waiting-spinner{width:24px;height:24px;border:3px solid #e0e0e0;border-top-color:var(--gs-accent,#2563eb);border-radius:50%;animation:spin .8s linear infinite}.gs-column-menu-waiting .gs-waiting-cancel-btn{font-size:12px;padding:4px 18px;border:1px solid #c33;border-radius:3px;background-color:transparent;color:#c33;cursor:pointer;font-weight:700;letter-spacing:1px}.gs-column-menu-waiting .gs-waiting-cancel-btn:hover{background-color:#c33;color:#fff}.gs-column-menu-btn{right:4px;top:50%;transform:translateY(-50%)}.gs-column-menu-btn.gs-filtered{opacity:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);border-color:var(--gs-accent,#2563eb);color:var(--gs-accent,#2563eb)}.gs-column-menu-btn.gs-active{opacity:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 18%,transparent);border-color:var(--gs-accent,#2563eb);color:var(--gs-accent,#2563eb)}.gs-th-top:hover .gs-column-menu-btn{opacity:1}.gs-row-menu{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;opacity:.9;transition:opacity .15s ease}.gs-row-menu:hover{opacity:1}.gs-row-menu ul{color:#555;margin:0;padding:0;min-width:200px}.gs-row-fixed-toggle{display:flex;align-items:center;gap:6px}.gs-row-fixed-check{font-size:12px;width:14px;text-align:center;color:transparent}.gs-row-fixed-check.gs-row-fixed-active{color:var(--gs-accent,#2563eb)}.gs-row-menu-btn{top:50%;transform:translateY(-50%);right:2px}.gs-row-menu-btn.gs-active{opacity:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 18%,transparent);border-color:var(--gs-accent,#2563eb);color:var(--gs-accent,#2563eb)}.gs-th-left:hover .gs-row-menu-btn{opacity:1}.gs-corner-menu-btn{bottom:2px;right:2px}.gs-corner-menu-btn:hover{opacity:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 18%,transparent);border-color:var(--gs-accent,#2563eb);color:var(--gs-accent,#2563eb)}.gs-th-left.gs-th-top:hover .gs-corner-menu-btn{opacity:1}.gs-editor-hl{padding:0 2px!important;position:absolute;font-family:monospace,Arial;font-size:12px;line-height:24px;letter-spacing:1px}.gs-formula-bar-editor-inner{position:relative;flex:1;min-width:0;display:flex;align-items:center}.gs-editor{opacity:0;z-index:-1}.gs-editor .gs-editor-inner{position:relative}.gs-editor .gs-editor-hl{box-sizing:content-box;border:solid 2px var(--gs-accent,#2563eb);margin:-2px -1px}.gs-editor textarea{width:100%;padding:0 2px!important;position:absolute;font-size:12px;font-family:monospace,Arial;line-height:24px;letter-spacing:1px;top:0;left:0;border:none;outline:0;background-color:transparent;color:transparent;resize:none;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;overflow:hidden;cursor:default;white-space:pre;height:auto}.gs-editor.gs-editing{z-index:11;opacity:1}.gs-editor.gs-editing .gs-cell-label{pointer-events:none;font-family:inherit;font-weight:500;position:absolute;top:0;right:0;margin-top:-17px;margin-right:-2px;padding:1px 5px;border-top-left-radius:4px;border-top-right-radius:4px;font-size:10px;background-color:var(--gs-accent,#2563eb);color:#fff;z-index:1}.gs-formula-bar{width:100%;position:relative;display:flex;align-items:stretch;box-sizing:border-box;border-style:solid;border-color:var(--gs-border,#e3e6ea);border-width:var(--gs-fb-bt,1px) var(--gs-fb-br,1px) var(--gs-fb-bb,1px) var(--gs-fb-bl,1px);padding:3px 6px;gap:6px}.gs-formula-bar .gs-selecting-address{display:flex;align-items:center;justify-content:center;min-width:38px;padding:0 4px;color:var(--gs-muted-fg,#6b7280);font-size:12px;font-variant-numeric:tabular-nums;text-align:center}.gs-formula-bar[data-spill=true]{background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 6%,var(--gs-header-bg,#f4f5f7))}.gs-formula-bar[data-spill=true] .gs-selecting-address{color:var(--gs-accent,#2563eb);font-style:italic}.gs-formula-bar[data-spill=true] .gs-selecting-address::after{content:"\2196";margin-left:2px;font-style:normal;font-size:9px}.gs-formula-bar .gs-fx{display:flex;align-items:center;justify-content:center;align-self:center;width:26px;height:18px;flex-shrink:0;color:var(--gs-muted-fg,#6b7280);font-style:italic;font-family:inherit;font-weight:400;text-align:center;font-size:13px;letter-spacing:.3px;border-radius:4px;background-color:color-mix(in srgb,var(--gs-fg,#1f2328) 6%,transparent)}.gs-formula-bar .gs-editor-hl{z-index:0;overflow-y:auto;box-sizing:border-box;white-space:pre-wrap;word-break:break-all;text-align:left;line-height:24px}.gs-formula-bar textarea{position:relative;z-index:1;width:100%;vertical-align:bottom;color:transparent;border:none;background-color:transparent;padding:0 2px;box-sizing:border-box;text-align:left;outline:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;font-size:12px;font-family:monospace,Arial;height:24px;line-height:24px;min-height:24px;letter-spacing:1px;resize:vertical;caret-color:var(--gs-fg,#1f2328);white-space:pre-wrap;word-break:break-all}.gs-token-type-INVALID_REF{color:red}.gs-token-type-VALUE.gs-token-entity-type-boolean,.gs-token-type-VALUE.gs-token-entity-type-number{color:#39f}.gs-token-type-VALUE.gs-token-entity-type-string{color:#090}.gs-editor-options{position:fixed;z-index:1000;padding:4px;background:var(--gs-bg,#fff);box-shadow:0 4px 12px rgba(0,0,0,.15);border:1px solid rgba(0,0,0,.1);border-radius:6px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;overflow:visible}.gs-editor-option{position:relative;cursor:pointer;list-style:none;padding:6px 12px;font-size:13px;border-radius:4px;color:#333;margin-bottom:2px}.gs-editor-option-content{display:flex;justify-content:space-between;width:100%;align-items:center}.gs-editor-option-tab{font-size:10px;color:#aaa;margin-left:8px;padding:2px 4px;border:1px solid #ddd;border-radius:3px;background:#f9f9f9}.gs-editor-option:last-child{margin-bottom:0}.gs-editor-option:hover{background-color:#f5f5f5}.gs-editor-option-selected{background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);color:var(--gs-accent,#2563eb);font-weight:500}.gs-editor-option-selected:hover{background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 18%,transparent)}.gs-fn-guide1{position:absolute;top:-4px;left:calc(100% + 8px);background:#fff;border:1px solid rgba(0,0,0,.1);box-shadow:0 4px 16px rgba(0,0,0,.12);border-radius:6px;padding:16px;width:280px;z-index:1000;cursor:default;white-space:normal;color:#333}.gs-fn-guide1-tooltip{margin-bottom:8px;line-height:1.4;font-size:13px}.gs-fn-guide1-example{font-family:monospace;font-weight:600;font-size:13px;margin-bottom:8px;color:#1a1a1a;background:#f5f5f5;padding:6px 8px;border-radius:4px;border:1px solid #eee;display:flex;align-items:center;gap:6px;flex-wrap:wrap}.gs-fn-guide1-desc{font-size:13px;color:#555;margin-bottom:12px;line-height:1.4}.gs-fn-guide1-desc p{margin:0 0 6px 0}.gs-fn-guide1-desc p:last-child{margin-bottom:0}.gs-fn-guide1-args{border-top:1px solid #eee;padding-top:10px}.gs-fn-guide1-arg{margin-bottom:6px;line-height:1.4;font-size:12px}.gs-fn-guide1-arg-name{font-weight:600;color:var(--gs-accent,#2563eb)}.gs-fn-guide1-arg-opt{color:#888;font-size:11px}.gs-fn-guide1-arg-iter{font-weight:600;color:var(--gs-accent,#2563eb)}.gs-fn-guide1-arg-type{color:var(--gs-accent,#2563eb);padding:0 4px;background:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);border-radius:3px;font-size:11px;margin:0 4px}.gs-fn-guide1-arg-desc{color:#666}.gs-fn-guide-category{position:absolute;top:-11px;right:8px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;font-size:11px;font-weight:600;letter-spacing:.5px;text-transform:uppercase;padding:2px 7px;border-radius:4px;background:#e8eaf6;color:#3949ab;border:1px solid #c5cae9;white-space:nowrap}.gs-fn-guide-category.gs-fn-guide-category-math{background:#e3f2fd;color:#1565c0;border-color:#bbdefb}.gs-fn-guide-category.gs-fn-guide-category-statistics{background:#e8f5e9;color:#2e7d32;border-color:#c8e6c9}.gs-fn-guide-category.gs-fn-guide-category-text{background:#fff8e1;color:#f57f17;border-color:#ffecb3}.gs-fn-guide-category.gs-fn-guide-category-time{background:#fce4ec;color:#880e4f;border-color:#f8bbd0}.gs-fn-guide-category.gs-fn-guide-category-lookup{background:#f3e5f5;color:#6a1b9a;border-color:#e1bee7}.gs-fn-guide-category.gs-fn-guide-category-logical{background:#e0f2f1;color:#00695c;border-color:#b2dfdb}.gs-fn-guide-category.gs-fn-guide-category-information{background:#e0f7fa;color:#006064;border-color:#b2ebf2}.gs-fn-guide-category.gs-fn-guide-category-finance{background:#fff3e0;color:#e65100;border-color:#ffe0b2}.gs-fn-guide-category.gs-fn-guide-category-engineering{background:#efebe9;color:#4e342e;border-color:#d7ccc8}.gs-fn-guide-category.gs-fn-guide-category-ai{background:#e8eaf6;color:#3949ab;border-color:#c5cae9}.gs-fn-guide-category.gs-fn-guide-category-other{background:#f5f5f5;color:#616161;border-color:#e0e0e0}.gs-editor-portal{display:contents}.gs-editor-portal[data-mode=dark] .gs-editor-options,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-options,.gs-editor[data-mode=dark] .gs-editor-options,.gs-editor[data-mode=inherit-dark] .gs-editor-options{background:#252526;border-color:#454545;box-shadow:0 4px 12px rgba(0,0,0,.5)}.gs-editor-portal[data-mode=dark] .gs-editor-option,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option,.gs-editor[data-mode=dark] .gs-editor-option,.gs-editor[data-mode=inherit-dark] .gs-editor-option{color:#ccc}.gs-editor-portal[data-mode=dark] .gs-editor-option:hover,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option:hover,.gs-editor[data-mode=dark] .gs-editor-option:hover,.gs-editor[data-mode=inherit-dark] .gs-editor-option:hover{background-color:#333}.gs-editor-portal[data-mode=dark] .gs-editor-option-selected,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option-selected,.gs-editor[data-mode=dark] .gs-editor-option-selected,.gs-editor[data-mode=inherit-dark] .gs-editor-option-selected{background-color:#094771;color:#fff}.gs-editor-portal[data-mode=dark] .gs-editor-option-selected:hover,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option-selected:hover,.gs-editor[data-mode=dark] .gs-editor-option-selected:hover,.gs-editor[data-mode=inherit-dark] .gs-editor-option-selected:hover{background-color:#0d5a8f}.gs-editor-portal[data-mode=dark] .gs-editor-option-tab,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option-tab,.gs-editor[data-mode=dark] .gs-editor-option-tab,.gs-editor[data-mode=inherit-dark] .gs-editor-option-tab{color:#777;background:#333;border-color:#444}.gs-editor-portal[data-mode=dark] .gs-fn-guide1,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1,.gs-editor[data-mode=dark] .gs-fn-guide1,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1{background:#252526;border-color:#454545;color:#ccc}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-example,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-example,.gs-editor[data-mode=dark] .gs-fn-guide1-example,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-example{background:#1e1e1e;border-color:#333;color:#d4d4d4}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-desc,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-desc,.gs-editor[data-mode=dark] .gs-fn-guide1-desc,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-desc{color:#aaa}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-args,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-args,.gs-editor[data-mode=dark] .gs-fn-guide1-args,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-args{border-color:#333}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-iter,.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-name,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-iter,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-name,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-iter,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-name,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-iter,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-name{color:#4fc1ff}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-opt,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-opt,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-opt,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-opt{color:#777}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-type,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-type,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-type,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-type{background:#094771;color:#4fc1ff}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-desc,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-desc,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-desc,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-desc{color:#999}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category,.gs-editor[data-mode=dark] .gs-fn-guide-category,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category{background:#2a2d3e;color:#7986cb;border-color:#3d4166}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-math,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-math,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-math,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-math{background:#0d2137;color:#64b5f6;border-color:#1a3a5c}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-statistics,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-statistics,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-statistics,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-statistics{background:#0d2218;color:#66bb6a;border-color:#1a3d2a}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-text,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-text,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-text,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-text{background:#2e2200;color:#ffd54f;border-color:#4d3900}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-time,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-time,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-time,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-time{background:#2d0d1e;color:#f48fb1;border-color:#4d1a33}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-lookup,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-lookup,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-lookup,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-lookup{background:#260d33;color:#ce93d8;border-color:#3d1a54}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-logical,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-logical,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-logical,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-logical{background:#0d2421;color:#4db6ac;border-color:#1a3d39}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-information,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-information,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-information,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-information{background:#0d2426;color:#4dd0e1;border-color:#1a3d40}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-finance,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-finance,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-finance,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-finance{background:#2e1500;color:#ffb74d;border-color:#4d2800}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-engineering,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-engineering,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-engineering,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-engineering{background:#1e1714;color:#bcaaa4;border-color:#332c28}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-ai,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-ai,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-ai,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-ai{background:#10142e;color:#7986cb;border-color:#232a52}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-other,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-other,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-other,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-other{background:#1e1e1e;color:#9e9e9e;border-color:#333}.gs-editor-portal[data-mode=dark] .gs-fn-guide2,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2,.gs-editor[data-mode=dark] .gs-fn-guide2,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2{background:#252526;border-color:#454545;box-shadow:0 4px 12px rgba(0,0,0,.5);color:#ccc}.gs-editor-portal[data-mode=dark] .gs-fn-guide2-name,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2-name,.gs-editor[data-mode=dark] .gs-fn-guide2-name,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2-name{color:#dfdbdb;background:#333;border-color:#444}.gs-editor-portal[data-mode=dark] .gs-fn-guide2 .gs-active-arg,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2 .gs-active-arg,.gs-editor[data-mode=dark] .gs-fn-guide2 .gs-active-arg,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2 .gs-active-arg{color:#fff;background-color:#094771}.gs-editor-portal[data-mode=dark] .gs-fn-guide2-arg-type,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2-arg-type,.gs-editor[data-mode=dark] .gs-fn-guide2-arg-type,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2-arg-type{background:#094771;color:#4fc1ff}.gs-editor-portal[data-mode=dark] .gs-fn-guide2-desc,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2-desc,.gs-editor[data-mode=dark] .gs-fn-guide2-desc,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2-desc{color:#aaa;border-top-color:#333}.gs-fn-guide2{position:fixed;left:0;background:#fff;border:1px solid rgba(0,0,0,.1);box-shadow:0 4px 16px rgba(0,0,0,.12);border-radius:6px;padding:12px 16px;width:280px;z-index:1000;cursor:default;white-space:normal;color:#333;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;transition:opacity .1s ease-in-out}.gs-fn-guide2.gs-fn-guide2-hidden{opacity:0!important;pointer-events:none!important}.gs-fn-guide2-name{font-family:monospace;font-weight:700;font-size:13px;color:#1a1a1a;background:#f5f5f5;padding:6px 8px;border-radius:4px;border:1px solid #eee;display:flex;align-items:center;gap:6px;flex-wrap:wrap;width:100%;box-sizing:border-box;margin-bottom:8px}.gs-fn-guide2-args-inline{font-size:13px;font-family:monospace;line-height:1.5;margin-bottom:8px;color:#666}.gs-fn-guide2-args-inline span{transition:all .2s ease-in-out}.gs-fn-guide2 .gs-active-arg{font-weight:700;color:var(--gs-accent,#2563eb);background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);padding:2px 4px;margin:0 -4px;border-radius:4px}.gs-fn-guide2-arg-type{color:var(--gs-accent,#2563eb);padding:0 4px;background:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);border-radius:3px;font-size:11px;margin:0 4px}.gs-fn-guide2-desc{font-size:12px;color:#555;line-height:1.4;border-top:1px solid #eee;padding-top:8px;margin-top:4px}.gs-fn-guide2-desc p{margin:0}.gs-fn-guide2-desc-more{font-style:italic;color:#888;margin-top:4px!important;font-size:11px}.gs-adjuster{padding:0}.gs-table{margin:0}.gs-tabular{overflow:auto;overflow-anchor:none;display:flex;box-sizing:border-box;position:relative}.gs-root1[data-matrix-align=both] .gs-tabular,.gs-root1[data-matrix-align=horizontal] .gs-tabular{justify-content:safe center}.gs-root1[data-matrix-align=both] .gs-tabular,.gs-root1[data-matrix-align=vertical] .gs-tabular{align-items:safe center}.gs-tabular-inner{flex:0 0 auto;position:relative;overflow:hidden;overflow:clip;box-sizing:border-box;border-right:solid var(--gs-mx-br,1px) var(--gs-border,#e3e6ea);border-bottom:solid var(--gs-mx-bb,1px) var(--gs-border,#e3e6ea)}.gs-tabular-inner>table{table-layout:fixed;border-collapse:collapse;border-spacing:0}.gs-ghost-cell{padding:0;box-sizing:border-box;border:dashed 1px var(--gs-border,#e3e6ea);background-color:var(--gs-surface,#fff);opacity:.5;cursor:crosshair}.gs-ghost-th{opacity:.5}.gs-ghost-th-top{top:0}.gs-ghost-th-left{left:0}.gs-main[data-overflow-x=true] .gs-tabular-inner{border-right-width:0}.gs-main[data-overflow-y=true] .gs-tabular-inner{border-bottom-width:0}.gs-main::after{content:'';position:absolute;inset:0;pointer-events:none;z-index:3;border:0 solid var(--gs-border,#e3e6ea)}.gs-main[data-overflow-x=true]::after{border-right-width:var(--gs-mx-br,1px)}.gs-main[data-overflow-y=true]::after{border-bottom-width:var(--gs-mx-bb,1px)}.gs-th{z-index:2;padding:0;position:sticky;font-size:13px;font-weight:400;box-sizing:border-box;vertical-align:top}.gs-th .gs-resizer{position:absolute;border-color:transparent;box-sizing:border-box;z-index:2}.gs-th .gs-resizer:hover{background-color:var(--gs-accent,#2563eb)}.gs-th .gs-resizer.gs-protected{display:none}.gs-th-inner{height:100%;box-sizing:border-box;vertical-align:middle;overflow:hidden;display:flex;align-items:center;justify-content:center}.gs-th-inner-wrap{height:100%;box-sizing:border-box;background-color:transparent}.gs-th-top{top:0;overflow:hidden}.gs-th-top .gs-resizer{top:0;right:0;width:3px;cursor:e-resize}.gs-th-top .gs-resizer.gs-dragging{border-right-style:dotted;height:1000000px!important;cursor:e-resize}.gs-th-left{left:0;overflow:hidden;min-width:30px;border-top:solid 1px var(--gs-border,#e3e6ea)}.gs-th-left .gs-resizer{left:0;bottom:0;height:3px;cursor:n-resize}.gs-th-left .gs-resizer.gs-dragging{border-bottom-style:dotted;width:1000000px!important;cursor:n-resize}.gs-th-top.gs-th-left{top:0;left:0;z-index:3;border:none!important}.gs-th-left.gs-filter-fixed .gs-th-inner::before{content:'‹\00a0'}.gs-th-left.gs-sort-fixed .gs-th-inner::after{content:'\00a0›'}.gs-col-addr{position:absolute;top:2px;right:4px;font-size:9px;opacity:.5;line-height:1;letter-spacing:.3px;pointer-events:none}.gs-search-bar{width:100%;display:flex;align-items:center;padding:3px 0;border-top:solid 1px rgba(128,128,128,.3);border-left:solid 1px rgba(128,128,128,.3);border-right:solid 1px rgba(128,128,128,.3);border-bottom:solid 1px rgba(128,128,128,.3);box-sizing:border-box;background-color:rgba(200,50,0,.2)}.gs-search-bar.gs-search-found{background-color:rgba(0,200,100,.2)}.gs-search-bar .gs-search-bar-inner{border-left:solid 1px rgba(128,128,128,.5)}.gs-search-bar .gs-search-bar-icon{border-left:solid 1px rgba(128,128,128,.3);display:flex;align-items:center;justify-content:center;width:30px;flex-shrink:0}.gs-search-bar .gs-search-input-wrapper{flex-grow:1;position:relative;display:flex;align-items:center;height:100%}.gs-search-bar .gs-search-input-ghost{position:absolute;left:2px;right:2px;top:0;bottom:0;pointer-events:none;font-size:12px;font-family:monospace,Arial;line-height:24px;letter-spacing:1px;white-space:pre-wrap;word-break:break-all;color:transparent;overflow:hidden}.gs-search-bar .gs-search-input-ghost .gs-search-ghost-hint{color:#aaa}.gs-search-bar textarea{background-color:transparent;border:none;padding:0 2px;box-sizing:border-box;outline:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;font-size:12px;font-family:monospace,Arial;height:24px;line-height:24px;min-height:24px;letter-spacing:1px;caret-color:rgba(128,128,128);white-space:pre-wrap;word-break:break-all;flex-grow:1;width:100%;resize:none}.gs-search-progress{color:#999;font-size:13px;width:60px;flex-shrink:0;white-space:nowrap;text-align:center}.gs-search-close{cursor:pointer;display:flex;align-items:center;justify-content:center;width:24px;flex-shrink:0}.gs-search-buttons{display:flex;align-items:center;white-space:nowrap;flex-shrink:0}.gs-search-button{display:inline-flex;cursor:pointer;margin:0 2px}.gs-search-button span{display:inline-block;font-size:11px;padding:3px 5px;background-color:rgba(128,128,128,.1);border:1px solid rgba(128,128,128,.3);border-radius:3px;transition:all .15s ease;line-height:1}.gs-search-button span:hover{background-color:rgba(128,128,128,.2)}.gs-search-button span.gs-search-button-on{color:var(--gs-accent,#2563eb);background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 22%,transparent);border-color:var(--gs-accent,#2563eb)}.gs-search-range span{white-space:nowrap;font-family:monospace}@keyframes spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}.gs-loading-overlay{position:absolute;top:0;left:0;right:0;bottom:0;background:color-mix(in srgb,var(--gs-surface,#fff) 70%,transparent);display:flex;align-items:center;justify-content:center;z-index:100;pointer-events:all}.gs-loading-spinner{width:32px;height:32px;border:3px solid color-mix(in srgb,var(--gs-fg,#1f2328) 12%,transparent);border-top-color:var(--gs-accent,#2563eb);border-radius:50%;animation:spin .8s linear infinite}.gs-progress-overlay{position:absolute;top:0;left:0;right:0;bottom:0;z-index:100;pointer-events:all;display:flex;align-items:center;justify-content:center}.gs-progress-box{min-width:240px;padding:16px 18px;border-radius:8px;background:var(--gs-editor-surface,#fff);border:1px solid var(--gs-border,#e3e6ea);box-shadow:0 6px 24px rgba(0,0,0,.28);display:flex;flex-direction:column;gap:10px}.gs-progress-head{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--gs-fg,#1f2328)}.gs-progress-head .gs-loading-spinner{width:15px;height:15px;border-width:2px}.gs-progress-track{height:6px;border-radius:3px;overflow:hidden;background:color-mix(in srgb,var(--gs-fg,#1f2328) 12%,transparent)}.gs-progress-fill{height:100%;border-radius:3px;background:var(--gs-accent,#2563eb);transition:width .1s linear}@keyframes gs-pending-slide{0%{left:-40%}100%{left:100%}}@keyframes gs-pending-pulse{0%{left:0;width:0}50%{left:0;width:100%}100%{left:100%;width:0}}@keyframes gs-flash{0%{opacity:0}20%{opacity:1}100%{opacity:0}}.gs-flash-overlay{position:absolute;inset:0;pointer-events:none;z-index:9999;background:color-mix(in srgb,var(--gs-accent,#2563eb) 15%,transparent);opacity:0}.gs-flash-overlay--active{animation:gs-flash .6s ease-out forwards} \ No newline at end of file +.gs-root1{display:inline-block;position:relative;border-spacing:0;width:fit-content;max-width:100%;overflow:auto;font-family:"SF Pro Text","SF Pro Icons","Helvetica Neue",Helvetica,Arial,Meiryo,sans-serif;visibility:hidden;opacity:0}.gs-root1.gs-initialized{visibility:visible;opacity:1;transition:opacity .2s ease-in-out}.gs-root1 .gs-main{flex:1;max-width:100%;overflow:hidden;position:relative;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box}.gs-root1 .gs-resizing{width:100%;height:100%;position:absolute;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 8%,transparent);top:0;left:0;z-index:2}.gs-root1 .gs-line-horizontal{width:100%}.gs-root1 .gs-line-vertical{height:100%}.gs-root1 .gs-line{position:relative;top:0;left:0;border:dotted 1px var(--gs-accent,#2563eb);box-sizing:border-box}.gs-root1 .gs-line span{font-size:10px;padding:3px;background-color:var(--gs-accent,#2563eb);color:#fff;margin:0;position:absolute;top:0;left:0}.gs-root1 .gs-scroll-handle{width:100%;height:100%;cursor:cell}.gs-hidden{visibility:hidden;position:absolute;top:0;left:0;width:0;height:0;overflow:hidden;pointer-events:none;z-index:-1}.gs-fixed{position:fixed;top:0;left:0;z-index:1}:where(.gs-root1[data-mode=light],.gs-editor[data-mode=light]){--gs-fg:#1f2328;--gs-muted-fg:#6b7280;--gs-border:#e3e6ea;--gs-bg:rgba(128, 128, 128, 0.07);--gs-canvas:transparent;--gs-surface:#ffffff;--gs-editor-surface:#ffffff;--gs-header-bg:#f4f5f7;--gs-header-fg:#59616b;--gs-accent:#2563eb}.gs-root1{background-color:var(--gs-bg);color:var(--gs-fg)}.gs-root1 .gs-main{background-color:var(--gs-canvas)}.gs-root1 .gs-tabular{background-color:var(--gs-canvas)}.gs-root1 .gs-sheet-body-data{background-color:var(--gs-surface)}.gs-root1 .gs-formula-bar{background-color:var(--gs-header-bg)}.gs-root1 .gs-formula-bar-editor-inner{color:var(--gs-fg)}.gs-root1 .gs-cell{border:solid 1px var(--gs-border)}.gs-root1 .gs-adjuster{background-color:var(--gs-border)}.gs-root1 .gs-tabular-inner{background-color:var(--gs-border)}.gs-root1 .gs-large-editor textarea{color:var(--gs-fg);caret-color:var(--gs-fg)}.gs-root1 .gs-th{background-color:var(--gs-header-bg);color:var(--gs-header-fg)}.gs-root1 .gs-th-top{border-left:solid 1px var(--gs-border)}.gs-root1 .gs-th-top .gs-th-inner{border-top:solid var(--gs-mx-bt,1px) var(--gs-border)}.gs-root1 .gs-th-left{border-top:solid 1px var(--gs-border)}.gs-root1 .gs-th-left .gs-th-inner{border-left:solid var(--gs-mx-bl,1px) var(--gs-border)}.gs-root1 .gs-search-bar{color:color-mix(in srgb,var(--gs-fg) 40%,transparent)}.gs-root1 .gs-search-bar textarea{color:var(--gs-fg);caret-color:var(--gs-fg)}.gs-editor.gs-editing textarea{caret-color:var(--gs-fg)}.gs-editor.gs-editing .gs-editor-hl{background-color:var(--gs-editor-surface);color:var(--gs-fg)}.gs-editor .gs-editor-options{color:var(--gs-fg);background-color:var(--gs-editor-surface);border:solid 1px var(--gs-border)}:where(.gs-root1[data-mode=dark],.gs-editor[data-mode=dark]){--gs-fg:#e4e6e9;--gs-muted-fg:#8b9096;--gs-border:#2c2f34;--gs-bg:rgba(128, 128, 128, 0.07);--gs-canvas:transparent;--gs-surface:#1c1e21;--gs-editor-surface:#1c1e21;--gs-header-bg:#212327;--gs-header-fg:#a6abb2;--gs-accent:#3b82f6}:where(.gs-root1[data-mode=auto],.gs-editor[data-mode=auto]){--gs-fg:#1f2328;--gs-muted-fg:#6b7280;--gs-border:#e3e6ea;--gs-bg:rgba(128, 128, 128, 0.07);--gs-canvas:transparent;--gs-surface:#ffffff;--gs-editor-surface:#ffffff;--gs-header-bg:#f4f5f7;--gs-header-fg:#59616b;--gs-accent:#2563eb}@media (prefers-color-scheme:dark){:where(.gs-root1[data-mode=auto],.gs-editor[data-mode=auto]){--gs-fg:#e4e6e9;--gs-muted-fg:#8b9096;--gs-border:#2c2f34;--gs-bg:rgba(128, 128, 128, 0.07);--gs-canvas:transparent;--gs-surface:#1c1e21;--gs-editor-surface:#1c1e21;--gs-header-bg:#212327;--gs-header-fg:#a6abb2;--gs-accent:#3b82f6}}:where(.gs-root1[data-mode=inherit-light],.gs-editor[data-mode=inherit-light]){--gs-fg:#1f2328;--gs-muted-fg:#6b7280;--gs-border:#e3e6ea;--gs-bg:rgba(128, 128, 128, 0.07);--gs-surface:#ffffff;--gs-editor-surface:#ffffff;--gs-header-bg:#f4f5f7;--gs-header-fg:#59616b;--gs-accent:#2563eb;--gs-bg:transparent;--gs-canvas:transparent;--gs-surface:transparent;--gs-header-bg:transparent}:where(.gs-root1[data-mode=inherit-dark],.gs-editor[data-mode=inherit-dark]){--gs-fg:#e4e6e9;--gs-muted-fg:#8b9096;--gs-border:#2c2f34;--gs-bg:rgba(128, 128, 128, 0.07);--gs-surface:#1c1e21;--gs-editor-surface:#1c1e21;--gs-header-bg:#212327;--gs-header-fg:#a6abb2;--gs-accent:#3b82f6;--gs-bg:transparent;--gs-canvas:transparent;--gs-surface:transparent;--gs-header-bg:transparent}.gs-root1[data-mode=inherit-dark] .gs-adjuster,.gs-root1[data-mode=inherit-dark] .gs-tabular-inner,.gs-root1[data-mode=inherit-light] .gs-adjuster,.gs-root1[data-mode=inherit-light] .gs-tabular-inner{background-color:transparent}.gs-root1[data-mode=inherit-light] .gs-th{background-color:rgba(128,128,128,.1);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}.gs-root1[data-mode=inherit-dark] .gs-th{background-color:rgba(128,128,128,.1);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}.gs-root1[data-gridlines=horizontal] .gs-cell{border-left-color:transparent;border-right-color:transparent}.gs-root1[data-gridlines=none] .gs-cell{border-color:transparent}.gs-root1[data-density=comfortable] .gs-cell-rendered{padding:0 10px}.gs-cell{transition:border-color .2s ease;padding:0;margin:0;box-sizing:border-box;position:relative;font-size:13px;letter-spacing:1px;line-height:24px;cursor:cell;user-select:none;-webkit-user-select:none;-moz-user-select:none}.gs-cell.gs-copying textarea:focus{outline:solid 1px var(--gs-accent,#2563eb)}.gs-cell.gs-selecting{z-index:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 7%,transparent)}.gs-cell.gs-selecting .gs-cell-label{display:block}.gs-cell.gs-choosing{margin-top:-1px;margin-left:-1px;z-index:1}.gs-cell.gs-choosing.gs-editing{color:transparent}.gs-cell.gs-choosing .gs-cell-label{display:block}.gs-cell.gs-pending .gs-cell-rendered{position:relative;overflow:hidden}.gs-cell.gs-pending .gs-cell-rendered::after{content:'';position:absolute;bottom:0;left:0;height:4px;width:40%;border-radius:1px;background:color-mix(in srgb,var(--gs-accent,#2563eb) 65%,transparent);animation:gs-pending-slide 1.4s ease-in-out infinite}.gs-cell .gs-formula-error-triangle{position:absolute;top:0;right:0;border-top:4px solid rgba(200,0,0,.9);border-right:4px solid rgba(200,0,0,.9);border-bottom:4px solid transparent;border-left:4px solid transparent;z-index:2;cursor:help}.gs-cell .gs-cell-label{font-size:10px;font-weight:500;font-style:normal;font-family:inherit;letter-spacing:.2px;line-height:1.4;position:absolute;top:0;right:0;background-color:var(--gs-accent,#2563eb);color:#fff;padding:1px 5px;border-bottom-left-radius:4px;display:none;opacity:.92}.gs-cell .gs-cell-inner-wrap{width:100%;height:100%;position:absolute;top:0;left:0}.gs-cell .gs-cell-inner{width:100%;height:100%;overflow:hidden;display:flex;box-sizing:border-box;border:none!important}.gs-cell .gs-cell-rendered{overflow:hidden;white-space:pre-wrap;cursor:cell;word-wrap:break-word;word-break:break-all;padding:0 6px;width:100%;height:100%}.gs-cell .gs-cell-rendered>*{position:relative}.gs-cell .gs-cell-rendered>.backface{z-index:0}.gs-cell .gs-autofill-drag{background-color:var(--gs-accent,#2563eb);position:absolute;width:7px;height:7px;bottom:0;right:0;cursor:crosshair;z-index:1}.gs-cell.gs-merged-host{z-index:1}.gs-cell.gs-merged-host.gs-selecting{background-color:transparent}.gs-cell.gs-merged-host.gs-selecting .gs-cell-inner-wrap{background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 7%,transparent)}.gs-cell.gs-merged-covered{z-index:0}.gs-th[data-x="1"] .gs-th-inner-wrap{border-left:none}.gs-th[data-y="1"] .gs-th-inner-wrap{border-top:none}.gs-formula-error-tooltip{position:fixed;background-color:rgba(35,8,8,.94);color:#fff;padding:6px 10px;border-radius:4px;border-left:3px solid rgba(220,50,50,.8);font-size:12px;line-height:1.5;max-width:260px;white-space:pre-wrap;word-break:break-word;box-shadow:0 3px 10px rgba(0,0,0,.4);z-index:100;pointer-events:none;letter-spacing:.3px}.gs-menu-modal{width:100%;height:100vh;z-index:12}.gs-label-input-label{font-size:13px;letter-spacing:1px}.gs-menu-divider{background-color:#aaa;padding:0;margin:5px 0;height:1px;list-style-type:none}.gs-menu-btn{position:absolute;background-color:rgba(128,128,128,.3);border:1px solid #ccc;border-radius:50%;cursor:pointer;font-size:12px;font-weight:700;line-height:1;color:#888;width:18px;height:18px;padding:0;display:flex;align-items:center;justify-content:center;opacity:0;transition:opacity .15s ease;z-index:2}.gs-context-menu{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;opacity:.9;transition:opacity .15s ease}.gs-context-menu:hover{opacity:1}.gs-context-menu .gs-menu-items{color:#555;margin:0;padding:0;min-width:250px}.gs-menu-item{padding:5px 10px;list-style-type:none;display:flex}.gs-menu-item.gs-enabled{cursor:pointer}.gs-menu-item.gs-enabled:hover{background-color:#eee}.gs-menu-item.gs-disabled{opacity:.5;cursor:not-allowed}.gs-menu-item .gs-menu-name{font-size:13px;letter-spacing:1px;flex:1}.gs-submenu-parent{position:relative;align-items:center}.gs-submenu-parent .gs-submenu-arrow{margin-left:8px;font-size:11px;opacity:.6}.gs-submenu-flyout{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;opacity:.9;transition:opacity .15s ease;min-width:200px;margin:0;color:#555;opacity:1;list-style-type:none}.gs-submenu-flyout:hover{opacity:1}.gs-menu-shortcut{font-size:10px;line-height:20px;color:#999}.gs-menu-shortcut:before{content:"( "}.gs-menu-shortcut:after{content:" )"}.gs-menu-shortcut .gs-menu-underline{text-decoration:underline}.gs-column-menu{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;opacity:.9;transition:opacity .15s ease}.gs-column-menu:hover{opacity:1}.gs-column-menu ul{color:#555;margin:0;padding:0;min-width:200px}.gs-column-menu .gs-column-menu-sort{align-items:center}.gs-column-menu .gs-column-menu-sort .gs-sort-buttons{display:flex;gap:4px;margin-left:auto}.gs-column-menu .gs-column-menu-sort .gs-sort-btn{font-size:12px;padding:4px 8px;border:1px solid transparent;border-radius:3px;background-color:rgba(180,180,180,.1);cursor:pointer;color:#555;font-weight:700;letter-spacing:.5px}.gs-column-menu .gs-column-menu-sort .gs-sort-btn:hover:not(:disabled){border-color:#555}.gs-column-menu .gs-column-menu-sort .gs-sort-btn:disabled{opacity:.5;cursor:not-allowed}.gs-column-menu .gs-column-menu-label{padding:5px 10px}.gs-column-menu .gs-label-input-row{display:flex;gap:4px;align-items:center}.gs-column-menu .gs-label-input{flex:1;font-size:13px;padding:4px 6px;border:none;border-bottom:1px solid #ccc;border-radius:0;outline:0;min-width:0;width:100px;background-color:transparent;box-shadow:none}.gs-column-menu .gs-label-input:focus{border-bottom-color:var(--gs-accent,#2563eb);outline:0;box-shadow:none}.gs-column-menu .gs-label-apply-btn{font-size:12px;padding:4px 8px;border:1px solid transparent;border-radius:3px;background-color:rgba(180,180,180,.1);cursor:pointer;color:#555;font-weight:700;letter-spacing:.5px}.gs-column-menu .gs-label-apply-btn:hover:not(:disabled){border-color:#555}.gs-column-menu .gs-label-apply-btn:disabled{opacity:.5;cursor:not-allowed}.gs-column-menu .gs-column-menu-filter{padding:5px 10px;list-style-type:none;font-size:13px}.gs-column-menu .gs-filter-header{display:flex;align-items:center;gap:8px}.gs-column-menu .gs-filter-header .gs-filter-add-btn{font-size:12px;padding:3px 9px;border:1px solid transparent;border-radius:3px;background-color:rgba(180,180,180,.1);cursor:pointer;color:#555;letter-spacing:1px}.gs-column-menu .gs-filter-header .gs-filter-add-btn:hover{border-color:#555}.gs-column-menu .gs-filter-mode-toggle{display:flex;gap:6px;margin-left:auto}.gs-column-menu .gs-filter-mode-toggle label{display:flex;align-items:center;gap:3px;font-size:11px;font-weight:700;letter-spacing:.5px;color:#888;cursor:pointer;user-select:none}.gs-column-menu .gs-filter-mode-toggle label input[type=radio]{margin:0;cursor:pointer}.gs-column-menu .gs-filter-mode-toggle label.gs-active{color:var(--gs-accent,#2563eb)}.gs-column-menu .gs-filter-mode-toggle.gs-disabled{opacity:.4;pointer-events:none}.gs-column-menu .gs-filter-conditions{display:flex;flex-direction:column;gap:5px;margin-top:6px;max-height:200px;overflow-y:auto}.gs-column-menu .gs-filter-condition-row{display:flex;gap:4px;align-items:normal}.gs-column-menu .gs-filter-method-select{font-size:12px;padding:4px 4px;border:none;border-bottom:1px solid #ccc;border-radius:0;outline:0;background-color:#fff;box-shadow:none;min-width:40px;max-width:80px;cursor:pointer}.gs-column-menu .gs-filter-method-select:focus{border-bottom-color:var(--gs-accent,#2563eb);outline:0;box-shadow:none}.gs-column-menu .gs-filter-value-input{flex:1;font-size:13px;padding:4px 6px;border:none;border-bottom:1px solid #ccc;border-radius:0;outline:0;min-width:0;width:80px;background-color:transparent;box-shadow:none}.gs-column-menu .gs-filter-value-input:focus{border-bottom-color:var(--gs-accent,#2563eb);outline:0;box-shadow:none}.gs-column-menu .gs-filter-remove-btn{font-size:12px;padding:0;border:none;border-radius:3px;background-color:transparent;cursor:pointer;color:#999;line-height:1;flex-shrink:0}.gs-column-menu .gs-filter-remove-btn:hover{color:#c33}.gs-column-menu .gs-filter-actions{display:flex;gap:4px;margin-top:10px;align-items:center}.gs-column-menu .gs-filter-actions .gs-filter-reset-all-btn{font-size:12px;padding:3px 9px;border:1px solid transparent;border-radius:3px;background-color:transparent;cursor:pointer;color:#c33;font-weight:700;letter-spacing:1px}.gs-column-menu .gs-filter-actions .gs-filter-reset-all-btn:hover{border-color:#c33}.gs-column-menu .gs-filter-actions .gs-filter-actions-right{display:flex;gap:4px;margin-left:auto}.gs-column-menu .gs-filter-actions .gs-filter-reset-btn{font-size:12px;padding:3px 9px;border:1px solid transparent;border-radius:3px;background-color:transparent;cursor:pointer;color:#e08000;font-weight:700;letter-spacing:1px}.gs-column-menu .gs-filter-actions .gs-filter-reset-btn:hover{border-color:#e08000}.gs-column-menu .gs-filter-actions .gs-filter-apply-btn{font-size:12px;padding:3px 6px;border:1px solid transparent;border-radius:3px;background-color:transparent;color:var(--gs-accent,#2563eb);cursor:pointer;font-weight:700;letter-spacing:1px}.gs-column-menu .gs-filter-actions .gs-filter-apply-btn:hover{border-color:var(--gs-accent,#2563eb)}.gs-column-menu-waiting{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:20px 30px;gap:12px;min-width:180px}.gs-column-menu-waiting .gs-waiting-message{font-size:13px;font-weight:700;color:#555;letter-spacing:.5px}.gs-column-menu-waiting .gs-waiting-spinner{width:24px;height:24px;border:3px solid #e0e0e0;border-top-color:var(--gs-accent,#2563eb);border-radius:50%;animation:spin .8s linear infinite}.gs-column-menu-waiting .gs-waiting-cancel-btn{font-size:12px;padding:4px 18px;border:1px solid #c33;border-radius:3px;background-color:transparent;color:#c33;cursor:pointer;font-weight:700;letter-spacing:1px}.gs-column-menu-waiting .gs-waiting-cancel-btn:hover{background-color:#c33;color:#fff}.gs-column-menu-btn{right:4px;top:50%;transform:translateY(-50%)}.gs-column-menu-btn.gs-filtered{opacity:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);border-color:var(--gs-accent,#2563eb);color:var(--gs-accent,#2563eb)}.gs-column-menu-btn.gs-active{opacity:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 18%,transparent);border-color:var(--gs-accent,#2563eb);color:var(--gs-accent,#2563eb)}.gs-th-top:hover .gs-column-menu-btn{opacity:1}.gs-row-menu{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;opacity:.9;transition:opacity .15s ease}.gs-row-menu:hover{opacity:1}.gs-row-menu ul{color:#555;margin:0;padding:0;min-width:200px}.gs-row-fixed-toggle{display:flex;align-items:center;gap:6px}.gs-row-fixed-check{font-size:12px;width:14px;text-align:center;color:transparent}.gs-row-fixed-check.gs-row-fixed-active{color:var(--gs-accent,#2563eb)}.gs-row-menu-btn{top:50%;transform:translateY(-50%);right:2px}.gs-row-menu-btn.gs-active{opacity:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 18%,transparent);border-color:var(--gs-accent,#2563eb);color:var(--gs-accent,#2563eb)}.gs-th-left:hover .gs-row-menu-btn{opacity:1}.gs-corner-menu-btn{bottom:2px;right:2px}.gs-corner-menu-btn:hover{opacity:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 18%,transparent);border-color:var(--gs-accent,#2563eb);color:var(--gs-accent,#2563eb)}.gs-th-left.gs-th-top:hover .gs-corner-menu-btn{opacity:1}.gs-editor-hl{padding:0 2px!important;position:absolute;font-family:monospace,Arial;font-size:12px;line-height:24px;letter-spacing:1px}.gs-formula-bar-editor-inner{position:relative;flex:1;min-width:0;display:flex;align-items:center}.gs-editor{opacity:0;z-index:-1}.gs-editor .gs-editor-inner{position:relative}.gs-editor .gs-editor-hl{box-sizing:content-box;border:solid 2px var(--gs-accent,#2563eb);margin:-2px -1px}.gs-editor textarea{width:100%;padding:0 2px!important;position:absolute;font-size:12px;font-family:monospace,Arial;line-height:24px;letter-spacing:1px;top:0;left:0;border:none;outline:0;background-color:transparent;color:transparent;resize:none;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;overflow:hidden;cursor:default;white-space:pre;height:auto}.gs-editor.gs-editing{z-index:11;opacity:1}.gs-editor.gs-editing .gs-cell-label{pointer-events:none;font-family:inherit;font-weight:500;position:absolute;top:0;right:0;margin-top:-17px;margin-right:-2px;padding:1px 5px;border-top-left-radius:4px;border-top-right-radius:4px;font-size:10px;background-color:var(--gs-accent,#2563eb);color:#fff;z-index:1}.gs-formula-bar{width:100%;position:relative;display:flex;align-items:stretch;box-sizing:border-box;border-style:solid;border-color:var(--gs-border,#e3e6ea);border-width:var(--gs-fb-bt,1px) var(--gs-fb-br,1px) var(--gs-fb-bb,1px) var(--gs-fb-bl,1px);padding:3px 6px;gap:6px}.gs-formula-bar .gs-selecting-address{display:flex;align-items:center;justify-content:center;min-width:38px;padding:0 4px;color:var(--gs-muted-fg,#6b7280);font-size:12px;font-variant-numeric:tabular-nums;text-align:center}.gs-formula-bar[data-spill=true]{background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 6%,var(--gs-header-bg,#f4f5f7))}.gs-formula-bar[data-spill=true] .gs-selecting-address{color:var(--gs-accent,#2563eb);font-style:italic}.gs-formula-bar[data-spill=true] .gs-selecting-address::after{content:"\2196";margin-left:2px;font-style:normal;font-size:9px}.gs-formula-bar .gs-fx{display:flex;align-items:center;justify-content:center;align-self:center;width:26px;height:18px;flex-shrink:0;color:var(--gs-muted-fg,#6b7280);font-style:italic;font-family:inherit;font-weight:400;text-align:center;font-size:13px;letter-spacing:.3px;border-radius:4px;background-color:color-mix(in srgb,var(--gs-fg,#1f2328) 6%,transparent)}.gs-formula-bar .gs-editor-hl{z-index:0;overflow-y:auto;box-sizing:border-box;white-space:pre-wrap;word-break:break-all;text-align:left;line-height:24px}.gs-formula-bar textarea{position:relative;z-index:1;width:100%;vertical-align:bottom;color:transparent;border:none;background-color:transparent;padding:0 2px;box-sizing:border-box;text-align:left;outline:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;font-size:12px;font-family:monospace,Arial;height:24px;line-height:24px;min-height:24px;letter-spacing:1px;resize:vertical;caret-color:var(--gs-fg,#1f2328);white-space:pre-wrap;word-break:break-all}.gs-token-type-INVALID_REF{color:red}.gs-token-type-VALUE.gs-token-entity-type-boolean,.gs-token-type-VALUE.gs-token-entity-type-number{color:#39f}.gs-token-type-VALUE.gs-token-entity-type-string{color:#090}.gs-editor-options{position:fixed;z-index:1000;padding:4px;background:var(--gs-bg,#fff);box-shadow:0 4px 12px rgba(0,0,0,.15);border:1px solid rgba(0,0,0,.1);border-radius:6px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;overflow:visible}.gs-editor-option{position:relative;cursor:pointer;list-style:none;padding:6px 12px;font-size:13px;border-radius:4px;color:#333;margin-bottom:2px}.gs-editor-option-content{display:flex;justify-content:space-between;width:100%;align-items:center}.gs-editor-option-tab{font-size:10px;color:#aaa;margin-left:8px;padding:2px 4px;border:1px solid #ddd;border-radius:3px;background:#f9f9f9}.gs-editor-option:last-child{margin-bottom:0}.gs-editor-option:hover{background-color:#f5f5f5}.gs-editor-option-selected{background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);color:var(--gs-accent,#2563eb);font-weight:500}.gs-editor-option-selected:hover{background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 18%,transparent)}.gs-fn-guide1{position:absolute;top:-4px;left:calc(100% + 8px);background:#fff;border:1px solid rgba(0,0,0,.1);box-shadow:0 4px 16px rgba(0,0,0,.12);border-radius:6px;padding:16px;width:280px;z-index:1000;cursor:default;white-space:normal;color:#333}.gs-fn-guide1-tooltip{margin-bottom:8px;line-height:1.4;font-size:13px}.gs-fn-guide1-example{font-family:monospace;font-weight:600;font-size:13px;margin-bottom:8px;color:#1a1a1a;background:#f5f5f5;padding:6px 8px;border-radius:4px;border:1px solid #eee;display:flex;align-items:center;gap:6px;flex-wrap:wrap}.gs-fn-guide1-desc{font-size:13px;color:#555;margin-bottom:12px;line-height:1.4}.gs-fn-guide1-desc p{margin:0 0 6px 0}.gs-fn-guide1-desc p:last-child{margin-bottom:0}.gs-fn-guide1-args{border-top:1px solid #eee;padding-top:10px}.gs-fn-guide1-arg{margin-bottom:6px;line-height:1.4;font-size:12px}.gs-fn-guide1-arg-name{font-weight:600;color:var(--gs-accent,#2563eb)}.gs-fn-guide1-arg-opt{color:#888;font-size:11px}.gs-fn-guide1-arg-iter{font-weight:600;color:var(--gs-accent,#2563eb)}.gs-fn-guide1-arg-type{color:var(--gs-accent,#2563eb);padding:0 4px;background:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);border-radius:3px;font-size:11px;margin:0 4px}.gs-fn-guide1-arg-desc{color:#666}.gs-fn-guide-category{position:absolute;top:-11px;right:8px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;font-size:11px;font-weight:600;letter-spacing:.5px;text-transform:uppercase;padding:2px 7px;border-radius:4px;background:#e8eaf6;color:#3949ab;border:1px solid #c5cae9;white-space:nowrap}.gs-fn-guide-category.gs-fn-guide-category-math{background:#e3f2fd;color:#1565c0;border-color:#bbdefb}.gs-fn-guide-category.gs-fn-guide-category-statistics{background:#e8f5e9;color:#2e7d32;border-color:#c8e6c9}.gs-fn-guide-category.gs-fn-guide-category-text{background:#fff8e1;color:#f57f17;border-color:#ffecb3}.gs-fn-guide-category.gs-fn-guide-category-time{background:#fce4ec;color:#880e4f;border-color:#f8bbd0}.gs-fn-guide-category.gs-fn-guide-category-lookup{background:#f3e5f5;color:#6a1b9a;border-color:#e1bee7}.gs-fn-guide-category.gs-fn-guide-category-logical{background:#e0f2f1;color:#00695c;border-color:#b2dfdb}.gs-fn-guide-category.gs-fn-guide-category-information{background:#e0f7fa;color:#006064;border-color:#b2ebf2}.gs-fn-guide-category.gs-fn-guide-category-finance{background:#fff3e0;color:#e65100;border-color:#ffe0b2}.gs-fn-guide-category.gs-fn-guide-category-engineering{background:#efebe9;color:#4e342e;border-color:#d7ccc8}.gs-fn-guide-category.gs-fn-guide-category-ai{background:#e8eaf6;color:#3949ab;border-color:#c5cae9}.gs-fn-guide-category.gs-fn-guide-category-other{background:#f5f5f5;color:#616161;border-color:#e0e0e0}.gs-editor-portal{display:contents}.gs-editor-portal[data-mode=dark] .gs-editor-options,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-options,.gs-editor[data-mode=dark] .gs-editor-options,.gs-editor[data-mode=inherit-dark] .gs-editor-options{background:#252526;border-color:#454545;box-shadow:0 4px 12px rgba(0,0,0,.5)}.gs-editor-portal[data-mode=dark] .gs-editor-option,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option,.gs-editor[data-mode=dark] .gs-editor-option,.gs-editor[data-mode=inherit-dark] .gs-editor-option{color:#ccc}.gs-editor-portal[data-mode=dark] .gs-editor-option:hover,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option:hover,.gs-editor[data-mode=dark] .gs-editor-option:hover,.gs-editor[data-mode=inherit-dark] .gs-editor-option:hover{background-color:#333}.gs-editor-portal[data-mode=dark] .gs-editor-option-selected,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option-selected,.gs-editor[data-mode=dark] .gs-editor-option-selected,.gs-editor[data-mode=inherit-dark] .gs-editor-option-selected{background-color:#094771;color:#fff}.gs-editor-portal[data-mode=dark] .gs-editor-option-selected:hover,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option-selected:hover,.gs-editor[data-mode=dark] .gs-editor-option-selected:hover,.gs-editor[data-mode=inherit-dark] .gs-editor-option-selected:hover{background-color:#0d5a8f}.gs-editor-portal[data-mode=dark] .gs-editor-option-tab,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option-tab,.gs-editor[data-mode=dark] .gs-editor-option-tab,.gs-editor[data-mode=inherit-dark] .gs-editor-option-tab{color:#777;background:#333;border-color:#444}.gs-editor-portal[data-mode=dark] .gs-fn-guide1,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1,.gs-editor[data-mode=dark] .gs-fn-guide1,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1{background:#252526;border-color:#454545;color:#ccc}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-example,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-example,.gs-editor[data-mode=dark] .gs-fn-guide1-example,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-example{background:#1e1e1e;border-color:#333;color:#d4d4d4}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-desc,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-desc,.gs-editor[data-mode=dark] .gs-fn-guide1-desc,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-desc{color:#aaa}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-args,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-args,.gs-editor[data-mode=dark] .gs-fn-guide1-args,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-args{border-color:#333}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-iter,.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-name,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-iter,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-name,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-iter,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-name,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-iter,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-name{color:#4fc1ff}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-opt,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-opt,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-opt,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-opt{color:#777}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-type,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-type,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-type,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-type{background:#094771;color:#4fc1ff}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-desc,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-desc,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-desc,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-desc{color:#999}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category,.gs-editor[data-mode=dark] .gs-fn-guide-category,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category{background:#2a2d3e;color:#7986cb;border-color:#3d4166}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-math,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-math,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-math,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-math{background:#0d2137;color:#64b5f6;border-color:#1a3a5c}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-statistics,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-statistics,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-statistics,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-statistics{background:#0d2218;color:#66bb6a;border-color:#1a3d2a}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-text,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-text,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-text,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-text{background:#2e2200;color:#ffd54f;border-color:#4d3900}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-time,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-time,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-time,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-time{background:#2d0d1e;color:#f48fb1;border-color:#4d1a33}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-lookup,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-lookup,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-lookup,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-lookup{background:#260d33;color:#ce93d8;border-color:#3d1a54}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-logical,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-logical,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-logical,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-logical{background:#0d2421;color:#4db6ac;border-color:#1a3d39}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-information,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-information,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-information,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-information{background:#0d2426;color:#4dd0e1;border-color:#1a3d40}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-finance,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-finance,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-finance,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-finance{background:#2e1500;color:#ffb74d;border-color:#4d2800}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-engineering,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-engineering,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-engineering,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-engineering{background:#1e1714;color:#bcaaa4;border-color:#332c28}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-ai,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-ai,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-ai,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-ai{background:#10142e;color:#7986cb;border-color:#232a52}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-other,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-other,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-other,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-other{background:#1e1e1e;color:#9e9e9e;border-color:#333}.gs-editor-portal[data-mode=dark] .gs-fn-guide2,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2,.gs-editor[data-mode=dark] .gs-fn-guide2,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2{background:#252526;border-color:#454545;box-shadow:0 4px 12px rgba(0,0,0,.5);color:#ccc}.gs-editor-portal[data-mode=dark] .gs-fn-guide2-name,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2-name,.gs-editor[data-mode=dark] .gs-fn-guide2-name,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2-name{color:#dfdbdb;background:#333;border-color:#444}.gs-editor-portal[data-mode=dark] .gs-fn-guide2 .gs-active-arg,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2 .gs-active-arg,.gs-editor[data-mode=dark] .gs-fn-guide2 .gs-active-arg,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2 .gs-active-arg{color:#fff;background-color:#094771}.gs-editor-portal[data-mode=dark] .gs-fn-guide2-arg-type,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2-arg-type,.gs-editor[data-mode=dark] .gs-fn-guide2-arg-type,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2-arg-type{background:#094771;color:#4fc1ff}.gs-editor-portal[data-mode=dark] .gs-fn-guide2-desc,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2-desc,.gs-editor[data-mode=dark] .gs-fn-guide2-desc,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2-desc{color:#aaa;border-top-color:#333}.gs-fn-guide2{position:fixed;left:0;background:#fff;border:1px solid rgba(0,0,0,.1);box-shadow:0 4px 16px rgba(0,0,0,.12);border-radius:6px;padding:12px 16px;width:280px;z-index:1000;cursor:default;white-space:normal;color:#333;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;transition:opacity .1s ease-in-out}.gs-fn-guide2.gs-fn-guide2-hidden{opacity:0!important;pointer-events:none!important}.gs-fn-guide2-name{font-family:monospace;font-weight:700;font-size:13px;color:#1a1a1a;background:#f5f5f5;padding:6px 8px;border-radius:4px;border:1px solid #eee;display:flex;align-items:center;gap:6px;flex-wrap:wrap;width:100%;box-sizing:border-box;margin-bottom:8px}.gs-fn-guide2-args-inline{font-size:13px;font-family:monospace;line-height:1.5;margin-bottom:8px;color:#666}.gs-fn-guide2-args-inline span{transition:all .2s ease-in-out}.gs-fn-guide2 .gs-active-arg{font-weight:700;color:var(--gs-accent,#2563eb);background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);padding:2px 4px;margin:0 -4px;border-radius:4px}.gs-fn-guide2-arg-type{color:var(--gs-accent,#2563eb);padding:0 4px;background:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);border-radius:3px;font-size:11px;margin:0 4px}.gs-fn-guide2-desc{font-size:12px;color:#555;line-height:1.4;border-top:1px solid #eee;padding-top:8px;margin-top:4px}.gs-fn-guide2-desc p{margin:0}.gs-fn-guide2-desc-more{font-style:italic;color:#888;margin-top:4px!important;font-size:11px}.gs-adjuster{padding:0}.gs-table{margin:0}.gs-tabular{overflow:auto;overflow-anchor:none;display:flex;box-sizing:border-box;position:relative}.gs-root1[data-matrix-align=both] .gs-tabular,.gs-root1[data-matrix-align=horizontal] .gs-tabular{justify-content:safe center}.gs-root1[data-matrix-align=both] .gs-tabular,.gs-root1[data-matrix-align=vertical] .gs-tabular{align-items:safe center}.gs-tabular-inner{flex:0 0 auto;position:relative;overflow:hidden;overflow:clip;box-sizing:border-box;border-right:solid var(--gs-mx-br,1px) var(--gs-border,#e3e6ea);border-bottom:solid var(--gs-mx-bb,1px) var(--gs-border,#e3e6ea)}.gs-tabular-inner>table{table-layout:fixed;border-collapse:collapse;border-spacing:0}.gs-ghost-layer{font-size:13px}.gs-ghost-layer .gs-ghost-panel{position:fixed;overflow:hidden;z-index:1000;cursor:crosshair}.gs-ghost-layer .gs-ghost-cell,.gs-ghost-layer .gs-ghost-th{position:absolute;box-sizing:border-box}.gs-ghost-layer .gs-ghost-cell{border:dashed 1px var(--gs-border,#e3e6ea);background-color:color-mix(in srgb,var(--gs-surface,#fff) 70%,transparent)}.gs-ghost-layer .gs-ghost-cell.gs-ghost-target{background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,var(--gs-surface,#fff));border-color:color-mix(in srgb,var(--gs-accent,#2563eb) 45%,transparent)}.gs-ghost-layer .gs-ghost-th{display:flex;align-items:center;justify-content:center;background-color:var(--gs-header-bg,#f6f7f9);color:var(--gs-header-fg,#555);border:dashed 1px var(--gs-border,#e3e6ea);opacity:.75}.gs-main[data-overflow-x=true] .gs-tabular-inner{border-right-width:0}.gs-main[data-overflow-y=true] .gs-tabular-inner{border-bottom-width:0}.gs-main::after{content:'';position:absolute;inset:0;pointer-events:none;z-index:3;border:0 solid var(--gs-border,#e3e6ea)}.gs-main[data-overflow-x=true]::after{border-right-width:var(--gs-mx-br,1px)}.gs-main[data-overflow-y=true]::after{border-bottom-width:var(--gs-mx-bb,1px)}.gs-th{z-index:2;padding:0;position:sticky;font-size:13px;font-weight:400;box-sizing:border-box;vertical-align:top}.gs-th .gs-resizer{position:absolute;border-color:transparent;box-sizing:border-box;z-index:2}.gs-th .gs-resizer:hover{background-color:var(--gs-accent,#2563eb)}.gs-th .gs-resizer.gs-protected{display:none}.gs-th-inner{height:100%;box-sizing:border-box;vertical-align:middle;overflow:hidden;display:flex;align-items:center;justify-content:center}.gs-th-inner-wrap{height:100%;box-sizing:border-box;background-color:transparent}.gs-th-top{top:0;overflow:hidden}.gs-th-top .gs-resizer{top:0;right:0;width:3px;cursor:e-resize}.gs-th-top .gs-resizer.gs-dragging{border-right-style:dotted;height:1000000px!important;cursor:e-resize}.gs-th-left{left:0;overflow:hidden;min-width:30px;border-top:solid 1px var(--gs-border,#e3e6ea)}.gs-th-left .gs-resizer{left:0;bottom:0;height:3px;cursor:n-resize}.gs-th-left .gs-resizer.gs-dragging{border-bottom-style:dotted;width:1000000px!important;cursor:n-resize}.gs-th-top.gs-th-left{top:0;left:0;z-index:3;border:none!important}.gs-th-left.gs-filter-fixed .gs-th-inner::before{content:'‹\00a0'}.gs-th-left.gs-sort-fixed .gs-th-inner::after{content:'\00a0›'}.gs-col-addr{position:absolute;top:2px;right:4px;font-size:9px;opacity:.5;line-height:1;letter-spacing:.3px;pointer-events:none}.gs-search-bar{width:100%;display:flex;align-items:center;padding:3px 0;border-top:solid 1px rgba(128,128,128,.3);border-left:solid 1px rgba(128,128,128,.3);border-right:solid 1px rgba(128,128,128,.3);border-bottom:solid 1px rgba(128,128,128,.3);box-sizing:border-box;background-color:rgba(200,50,0,.2)}.gs-search-bar.gs-search-found{background-color:rgba(0,200,100,.2)}.gs-search-bar .gs-search-bar-inner{border-left:solid 1px rgba(128,128,128,.5)}.gs-search-bar .gs-search-bar-icon{border-left:solid 1px rgba(128,128,128,.3);display:flex;align-items:center;justify-content:center;width:30px;flex-shrink:0}.gs-search-bar .gs-search-input-wrapper{flex-grow:1;position:relative;display:flex;align-items:center;height:100%}.gs-search-bar .gs-search-input-ghost{position:absolute;left:2px;right:2px;top:0;bottom:0;pointer-events:none;font-size:12px;font-family:monospace,Arial;line-height:24px;letter-spacing:1px;white-space:pre-wrap;word-break:break-all;color:transparent;overflow:hidden}.gs-search-bar .gs-search-input-ghost .gs-search-ghost-hint{color:#aaa}.gs-search-bar textarea{background-color:transparent;border:none;padding:0 2px;box-sizing:border-box;outline:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;font-size:12px;font-family:monospace,Arial;height:24px;line-height:24px;min-height:24px;letter-spacing:1px;caret-color:rgba(128,128,128);white-space:pre-wrap;word-break:break-all;flex-grow:1;width:100%;resize:none}.gs-search-progress{color:#999;font-size:13px;width:60px;flex-shrink:0;white-space:nowrap;text-align:center}.gs-search-close{cursor:pointer;display:flex;align-items:center;justify-content:center;width:24px;flex-shrink:0}.gs-search-buttons{display:flex;align-items:center;white-space:nowrap;flex-shrink:0}.gs-search-button{display:inline-flex;cursor:pointer;margin:0 2px}.gs-search-button span{display:inline-block;font-size:11px;padding:3px 5px;background-color:rgba(128,128,128,.1);border:1px solid rgba(128,128,128,.3);border-radius:3px;transition:all .15s ease;line-height:1}.gs-search-button span:hover{background-color:rgba(128,128,128,.2)}.gs-search-button span.gs-search-button-on{color:var(--gs-accent,#2563eb);background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 22%,transparent);border-color:var(--gs-accent,#2563eb)}.gs-search-range span{white-space:nowrap;font-family:monospace}@keyframes spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}.gs-loading-overlay{position:absolute;top:0;left:0;right:0;bottom:0;background:color-mix(in srgb,var(--gs-surface,#fff) 70%,transparent);display:flex;align-items:center;justify-content:center;z-index:100;pointer-events:all}.gs-loading-spinner{width:32px;height:32px;border:3px solid color-mix(in srgb,var(--gs-fg,#1f2328) 12%,transparent);border-top-color:var(--gs-accent,#2563eb);border-radius:50%;animation:spin .8s linear infinite}.gs-progress-overlay{position:absolute;top:0;left:0;right:0;bottom:0;z-index:100;pointer-events:all;display:flex;align-items:center;justify-content:center}.gs-progress-box{min-width:240px;padding:16px 18px;border-radius:8px;background:var(--gs-editor-surface,#fff);border:1px solid var(--gs-border,#e3e6ea);box-shadow:0 6px 24px rgba(0,0,0,.28);display:flex;flex-direction:column;gap:10px}.gs-progress-head{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--gs-fg,#1f2328)}.gs-progress-head .gs-loading-spinner{width:15px;height:15px;border-width:2px}.gs-progress-track{height:6px;border-radius:3px;overflow:hidden;background:color-mix(in srgb,var(--gs-fg,#1f2328) 12%,transparent)}.gs-progress-fill{height:100%;border-radius:3px;background:var(--gs-accent,#2563eb);transition:width .1s linear}@keyframes gs-pending-slide{0%{left:-40%}100%{left:100%}}@keyframes gs-pending-pulse{0%{left:0;width:0}50%{left:0;width:100%}100%{left:100%;width:0}}@keyframes gs-flash{0%{opacity:0}20%{opacity:1}100%{opacity:0}}.gs-flash-overlay{position:absolute;inset:0;pointer-events:none;z-index:9999;background:color-mix(in srgb,var(--gs-accent,#2563eb) 15%,transparent);opacity:0}.gs-flash-overlay--active{animation:gs-flash .6s ease-out forwards} \ No newline at end of file diff --git a/packages/web/src/styles/tabular.less b/packages/web/src/styles/tabular.less index f5685e91..8d0ec320 100644 --- a/packages/web/src/styles/tabular.less +++ b/packages/web/src/styles/tabular.less @@ -48,24 +48,39 @@ } } -// autoExpand ghost rows/columns: the not-yet-existing cells past the last row/column, rendered -// only while an autofill is dragged on an auto-expanding sheet so the drag can reach them. -.gs-ghost-cell { - padding: 0; - box-sizing: border-box; - border: dashed 1px var(--gs-border, #e3e6ea); - background-color: var(--gs-surface, #ffffff); - opacity: 0.5; - cursor: crosshair; -} -.gs-ghost-th { - opacity: 0.5; -} -.gs-ghost-th-top { - top: 0; -} -.gs-ghost-th-left { - left: 0; +// autoExpand ghost rows/columns: the not-yet-existing cells drawn OUTSIDE the grid (portaled to +// , positioned fixed past the last row/column) while an autofill is dragged on an +// auto-expanding sheet, so the drag can reach them. Theme tokens are copied onto the layer. +.gs-ghost-layer { + font-size: 13px; + .gs-ghost-panel { + position: fixed; + overflow: hidden; + z-index: 1000; + cursor: crosshair; + } + .gs-ghost-cell, + .gs-ghost-th { + position: absolute; + box-sizing: border-box; + } + .gs-ghost-cell { + border: dashed 1px var(--gs-border, #e3e6ea); + background-color: color-mix(in srgb, var(--gs-surface, #ffffff) 70%, transparent); + &.gs-ghost-target { + background-color: color-mix(in srgb, var(--gs-accent, #2563eb) 12%, var(--gs-surface, #ffffff)); + border-color: color-mix(in srgb, var(--gs-accent, #2563eb) 45%, transparent); + } + } + .gs-ghost-th { + display: flex; + align-items: center; + justify-content: center; + background-color: var(--gs-header-bg, #f6f7f9); + color: var(--gs-header-fg, #555); + border: dashed 1px var(--gs-border, #e3e6ea); + opacity: 0.75; + } } // When an axis overflows, the hugging inner border would scroll out of view, so move that From 725951fcfe22306a52f4286b775da36d6394097f Mon Sep 17 00:00:00 2001 From: righ <8147077+righ@users.noreply.github.com> Date: Mon, 5 Oct 2026 21:42:22 +0900 Subject: [PATCH 6/6] feat(react-core): Handsontable-style provisional ghost rows/cols for autofill MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaces the outside-the-sheet ghost layer with provisional ghost rows/columns rendered inside the grid (as table rows/cells, so sticky headers stay): - While the fill drag's pointer is past the grid content's edge (the whitespace of a larger box, or outside it) and the grid is scrolled to that edge, add one ghost row/col at a time, faster the further past the edge (200ms → 20ms). - Ghosts are display-only (no sheet change, no history); releasing grows the sheet up to the reached row/col in one undo step, unreached ghosts vanish. - The target follows the last ghost while past the edge, the grid stays pinned to that edge as it grows, and growth stops once the pointer is back over a cell. The edge ScrollHandle no longer snaps the target back to the last real row/col there. - An autofill that grew the sheet scrolls the filled corner into view. - Storybook AutoExpand story: limits raised to 1000 rows x 100 cols. Co-Authored-By: Claude Opus 5.5 --- e2e/auto-expand.spec.ts | 108 ++++++-- .../src/components/AutofillGhost.tsx | 219 ----------------- .../src/components/ScrollHandle.tsx | 40 ++- .../src/components/StoreObserver.tsx | 12 +- .../react-core/src/components/Tabular.tsx | 231 +++++++++++++++++- packages/react-core/src/store/actions.ts | 11 +- .../restriction/autoExpand.stories.tsx | 4 +- packages/web/src/lib/virtualization.ts | 10 +- packages/web/src/styles/minified.ts | 4 +- packages/web/src/styles/root.min.css | 2 +- packages/web/src/styles/tabular.less | 51 ++-- 11 files changed, 396 insertions(+), 296 deletions(-) delete mode 100644 packages/react-core/src/components/AutofillGhost.tsx diff --git a/e2e/auto-expand.spec.ts b/e2e/auto-expand.spec.ts index 70438969..08c90f3f 100644 --- a/e2e/auto-expand.spec.ts +++ b/e2e/auto-expand.spec.ts @@ -60,33 +60,107 @@ test("'vertical' grows rows only", async ({ page }) => { await expect(page.locator("[data-address='E1']")).toHaveCount(0); }); -test('autofill dragged past the last row fills the ghost rows', async ({ page }) => { +test('autofill held past the last row adds provisional rows, committed on release', async ({ page }) => { await go(page, STORY); await setMode(page, 'vertical'); - // Select the 1,2,3 series and drag its fill handle below the grid. + // Select the 1,2,3 series and drag its fill handle below the grid, then hold. await drag(page, 'A1', 'A3'); - const handle = page.locator("[data-address='A3'] .gs-autofill-drag"); - const hb = await handle.boundingBox(); + const hb = await page.locator("[data-address='A3'] .gs-autofill-drag").boundingBox(); const tb = await page.locator('.gs-tabular').boundingBox(); await page.mouse.move(hb!.x + hb!.width / 2, hb!.y + hb!.height / 2); await page.mouse.down(); - await page.mouse.move(hb!.x + hb!.width / 2, tb!.y + tb!.height - 4, { steps: 5 }); - // Ghost rows are drawn outside the grid, right below its last row, while dragging. - const ghost = page.locator(".gs-ghost-cell[data-y='8'][data-x='1']"); - await expect(ghost).toBeVisible(); - const gb = await ghost.boundingBox(); - expect(gb!.y).toBeGreaterThanOrEqual(tb!.y + tb!.height - 2); // outside the sheet box - // Drag down onto the 3rd ghost row (row 8). - await page.mouse.move(gb!.x + gb!.width / 2, gb!.y + gb!.height / 2, { steps: 4 }); + await page.mouse.move(hb!.x + hb!.width / 2, tb!.y + tb!.height + 20, { steps: 5 }); + // Provisional rows appear one by one (Handsontable-style) — display only, the sheet is untouched. + await expect(page.locator('.gs-ghost-row').first()).toBeAttached(); + await page.waitForTimeout(1200); + await expect(page.locator('.gs-root1')).toHaveAttribute('data-rows', '5'); + expect(await page.locator('.gs-ghost-row').count()).toBeGreaterThan(1); await page.mouse.up(); await expect(page.locator('.gs-ghost-cell')).toHaveCount(0); - // Rows 6..8 were appended and the series continued into them. - expect(await text(page, 'A8')).toBe('8'); - await expect(page.locator("[data-address='A9']")).toHaveCount(0); + // Rows were appended on release and the series continued into them. + const rows = Number(await page.locator('.gs-root1').getAttribute('data-rows')); + expect(rows).toBeGreaterThan(6); + expect(await text(page, `A${rows}`)).toBe(String(rows)); + // One undo removes both the rows and the fill. await ctrl(page, 'z'); - await expect(page.locator("[data-address='A6']")).toHaveCount(0); - expect(await text(page, 'A5')).toBe(''); + await expect(page.locator('.gs-root1')).toHaveAttribute('data-rows', '5'); + await page.locator('.gs-tabular').evaluate((el) => (el.scrollTop = 0)); + expect(await text(page, 'A4')).toBe(''); +}); + +test('provisional rows vanish when the fill is dragged back before release', async ({ page }) => { + await go(page, STORY); + await setMode(page, 'vertical'); + + await drag(page, 'A1', 'A3'); + const hb = await page.locator("[data-address='A3'] .gs-autofill-drag").boundingBox(); + const tb = await page.locator('.gs-tabular').boundingBox(); + await page.mouse.move(hb!.x + hb!.width / 2, hb!.y + hb!.height / 2); + await page.mouse.down(); + await page.mouse.move(hb!.x + hb!.width / 2, tb!.y + tb!.height + 20, { steps: 5 }); + await page.waitForTimeout(600); + // Back onto the selection itself (no fill), then release. + await page.locator('.gs-tabular').evaluate((el) => (el.scrollTop = 0)); + await page.locator("[data-address='A2']").hover(); + await page.mouse.up(); + + await expect(page.locator('.gs-ghost-cell')).toHaveCount(0); + await expect(page.locator('.gs-root1')).toHaveAttribute('data-rows', '5'); +}); + +for (const dir of ['down', 'right'] as const) { + test(`leaving an enlarged box before its whitespace fills keeps growing (${dir})`, async ({ page }) => { + // Regression: with whitespace left in a resized box, exiting the box snapped the target back to + // the last real row/col (edge scroll handle) and the provisional ghosts stopped growing. + await page.setViewportSize({ width: 800, height: 700 }); + await go(page, STORY); + const b = await page.locator('.gs-main').boundingBox(); + await page.mouse.move(b!.x + b!.width - 3, b!.y + b!.height - 3); + await page.mouse.down(); + await page.mouse.move(b!.x + b!.width + 150, b!.y + b!.height + 230, { steps: 8 }); + await page.mouse.up(); + + await page.locator("[data-address='A1']").click(); + const hb = await page.locator("[data-address='A1'] .gs-autofill-drag").boundingBox(); + const tb = await page.locator('.gs-tabular').boundingBox(); + const grid = await page.locator('.gs-tabular-inner').boundingBox(); + await page.mouse.move(hb!.x + 3, hb!.y + 3); + await page.mouse.down(); + if (dir === 'down') { + await page.mouse.move(hb!.x + 3, grid!.y + grid!.height + 10, { steps: 5 }); // a little into the whitespace + await page.mouse.move(hb!.x + 3, tb!.y + tb!.height + 40, { steps: 2 }); // straight out of the box + } else { + await page.mouse.move(grid!.x + grid!.width + 10, hb!.y + 3, { steps: 5 }); + await page.mouse.move(tb!.x + tb!.width + 40, hb!.y + 3, { steps: 2 }); + } + await page.waitForTimeout(1000); + const ghosts = dir === 'down' ? '.gs-ghost-row' : '.gs-ghost-th-top'; + expect(await page.locator(ghosts).count()).toBeGreaterThan(4); + await page.mouse.up(); + }); +} + +test('provisional rows stop growing once the pointer is back over a cell', async ({ page }) => { + await page.setViewportSize({ width: 800, height: 700 }); + await go(page, STORY); + await setMode(page, 'vertical'); + + await drag(page, 'A1', 'A3'); + const hb = await page.locator("[data-address='A3'] .gs-autofill-drag").boundingBox(); + const tb = await page.locator('.gs-tabular').boundingBox(); + await page.mouse.move(hb!.x + 3, hb!.y + 3); + await page.mouse.down(); + await page.mouse.move(hb!.x + 3, tb!.y + tb!.height + 30, { steps: 4 }); // past the edge: grows + await page.waitForTimeout(800); + // Back inside the grid, over a (ghost) cell, and hold still. + await page.mouse.move(hb!.x + 3, tb!.y + tb!.height - 30, { steps: 3 }); + await page.waitForTimeout(300); + const settled = await page.locator('.gs-ghost-row').count(); + expect(settled).toBeGreaterThan(1); + await page.waitForTimeout(1000); + expect(await page.locator('.gs-ghost-row').count()).toBe(settled); + await page.mouse.up(); }); diff --git a/packages/react-core/src/components/AutofillGhost.tsx b/packages/react-core/src/components/AutofillGhost.tsx deleted file mode 100644 index 951c825f..00000000 --- a/packages/react-core/src/components/AutofillGhost.tsx +++ /dev/null @@ -1,219 +0,0 @@ -import { useCallback, useContext, useEffect, useState } from 'react'; -import type { CSSProperties, FC } from 'react'; -import { createPortal } from 'react-dom'; - -import { Context } from '../store'; -import { setAutofillDraggingTo } from '../store/actions'; -import { useBrowser } from '../lib/hooks'; -import { Autofill, among, getGhostCellSize, x2c } from '@gridsheet/web'; -import type { Sheet } from '@gridsheet/web'; - -// Ghost rows/cols kept beyond the drag target, so there is always room to drag further. -const GHOST_ROWS = 5; -const GHOST_COLS = 2; - -// Theme tokens the ghost cells use. The layer is portaled to (outside .gs-root1, whose -// overflow would clip anything drawn past the grid), so copy the resolved values over. -const THEME_VARS = ['--gs-border', '--gs-surface', '--gs-header-bg', '--gs-header-fg', '--gs-accent', '--gs-fg']; - -/** - * How many ghost rows/cols to show past the sheet's edge while an autofill is dragged on an - * auto-expanding sheet — enough to reach the current drag target plus some slack, capped by - * the max limits. Zero when the sheet can't grow that way. - */ -const getGhostCount = (sheet: Sheet, draggingTo: { y: number; x: number }) => { - const mode = sheet.autoExpand; - const room = (limit: number, current: number) => (limit === -1 ? Infinity : Math.max(0, limit - current)); - const rows = - mode === 'vertical' || mode === 'both' - ? Math.min(room(sheet.maxNumRows, sheet.numRows), Math.max(0, draggingTo.y - sheet.numRows) + GHOST_ROWS) - : 0; - const cols = - mode === 'horizontal' || mode === 'both' - ? Math.min(room(sheet.maxNumCols, sheet.numCols), Math.max(0, draggingTo.x - sheet.numCols) + GHOST_COLS) - : 0; - return { rows, cols }; -}; - -type Band = { index: number; start: number; size: number }; - -// The rendered header cells give each visible row/column's on-screen position, which already -// accounts for scrolling, the scroll-height remap and a centered matrix. -const readBands = (tabular: HTMLElement, selector: string, key: 'x' | 'y', horizontal: boolean): Band[] => - Array.from(tabular.querySelectorAll(selector)) - .filter((th) => th.dataset[key] != null) - .map((th) => { - const r = th.getBoundingClientRect(); - return { - index: Number(th.dataset[key]), - start: horizontal ? r.left : r.top, - size: horizontal ? r.width : r.height, - }; - }); - -/** - * The autoExpand ghost area: the not-yet-existing rows (below) / columns (right) drawn OUTSIDE - * the grid, right past its last row/column, while an autofill is dragged on an auto-expanding - * sheet. Dragging onto a ghost cell targets it; releasing grows the sheet (see Autofill). - * Shown only once the grid is scrolled to that edge, so the ghost always continues the last row/col. - */ -export const AutofillGhost: FC = () => { - const { store, dispatch } = useContext(Context); - const { sheetReactive, tabularRef, rootRef, autofillDraggingTo, mode } = store; - const sheet = sheetReactive.current; - const { document: doc } = useBrowser(); - const [, setTick] = useState(0); - const active = !!sheet && !!autofillDraggingTo && sheet.autoExpand !== 'none'; - - // Positions are read from the DOM, so re-render on anything that moves the grid. - useEffect(() => { - if (!active) { - return; - } - const bump = () => setTick((t) => t + 1); - const el = tabularRef.current; - el?.addEventListener('scroll', bump); - window.addEventListener('resize', bump); - window.addEventListener('scroll', bump, true); - return () => { - el?.removeEventListener('scroll', bump); - window.removeEventListener('resize', bump); - window.removeEventListener('scroll', bump, true); - }; - }, [active, tabularRef]); - - const handleEnter = useCallback( - (e: React.MouseEvent) => { - const y = Number(e.currentTarget.dataset.y); - const x = Number(e.currentTarget.dataset.x); - if (autofillDraggingTo && (y !== autofillDraggingTo.y || x !== autofillDraggingTo.x)) { - dispatch(setAutofillDraggingTo({ y, x })); - } - }, - [autofillDraggingTo], - ); - - const tabular = tabularRef.current; - const inner = tabular?.querySelector(':scope > .gs-tabular-inner'); - if (!active || !doc || !tabular || !inner || !sheet || !autofillDraggingTo) { - return null; - } - - const count = getGhostCount(sheet, autofillDraggingTo); - const ghost = getGhostCellSize(sheet); - const tab = tabular.getBoundingClientRect(); - const grid = inner.getBoundingClientRect(); - // The grid's last row/col is on screen only when scrolled to that edge. - const atBottom = tabular.scrollTop + tabular.clientHeight >= tabular.scrollHeight - 1; - const atRight = tabular.scrollLeft + tabular.clientWidth >= tabular.scrollWidth - 1; - const showRows = count.rows > 0 && atBottom; - const showCols = count.cols > 0 && atRight; - if (!showRows && !showCols) { - return null; - } - - const fillArea = new Autofill(store, autofillDraggingTo).wholeArea; - const viewLeft = tab.left + tabular.clientLeft; - const viewTop = tab.top + tabular.clientTop; - const viewRight = viewLeft + tabular.clientWidth; - const viewBottom = viewTop + tabular.clientHeight; - const gridRight = Math.min(grid.right, viewRight); - const gridBottom = Math.min(grid.bottom, viewBottom); - const headerW = sheet.headerWidth; - const headerH = sheet.headerHeight; - - const cols = readBands(tabular, '.gs-th-top', 'x', true); - const rows = readBands(tabular, '.gs-th-left', 'y', false); - const ghostCols: Band[] = showCols - ? Array.from({ length: count.cols }, (_, i) => ({ - index: sheet.numCols + 1 + i, - start: gridRight + i * ghost.width, - size: ghost.width, - })) - : []; - - const cell = (y: number, x: number, style: CSSProperties) => ( -
- ); - - const vars: Record = {}; - if (rootRef.current) { - const cs = getComputedStyle(rootRef.current); - THEME_VARS.forEach((v) => (vars[v] = cs.getPropertyValue(v))); - vars.fontFamily = cs.fontFamily; - } - - return createPortal( -
- {showRows && ( - // Rows below the grid: one per ghost row, cells under each visible (and ghost) column. -
- {Array.from({ length: count.rows }, (_, i) => { - const y = sheet.numRows + 1 + i; - const top = i * ghost.height; - return [ - ...[...cols, ...ghostCols].map((c) => - cell(y, c.index, { left: c.start - viewLeft, top, width: c.size, height: ghost.height }), - ), -
- {y} -
, - ]; - })} -
- )} - {showCols && ( - // Columns right of the grid: a header per ghost column, cells beside each visible row. -
- {ghostCols.map((c, i) => [ - ...rows - .filter((r) => r.start + r.size > viewTop + headerH) - .map((r) => - cell(r.index, c.index, { - left: i * ghost.width, - top: r.start - viewTop, - width: c.size, - height: r.size, - }), - ), -
- {x2c(c.index)} -
, - ])} -
- )} -
, - doc.body, - ); -}; diff --git a/packages/react-core/src/components/ScrollHandle.tsx b/packages/react-core/src/components/ScrollHandle.tsx index c07a42ce..3238de0b 100644 --- a/packages/react-core/src/components/ScrollHandle.tsx +++ b/packages/react-core/src/components/ScrollHandle.tsx @@ -72,6 +72,29 @@ export function ScrollHandle({ style, horizontal = 0, vertical = 0, className = [sheet, horizontal, vertical, selectingZone], ); + // The autoExpand ghost cell just inside the scrolling edge, if any. getDestEdge finds the edge + // from header cells, which ghost rows/cols don't have. This strip sits on top of the grid, + // so look through it with elementsFromPoint. + const getGhostEdgePoint = useCallback( + (e: React.MouseEvent) => { + const el = tabularRef.current; + if (!el) { + return null; + } + const r = el.getBoundingClientRect(); + const px = horizontal > 0 ? r.right - 2 : Math.min(Math.max(e.clientX, r.left + 1), r.right - 2); + const py = vertical > 0 ? r.bottom - 2 : Math.min(Math.max(e.clientY, r.top + 1), r.bottom - 2); + const ghost = document + .elementsFromPoint(px, py) + .find((node) => (node as HTMLElement).classList?.contains('gs-ghost-cell')) as HTMLElement | undefined; + if (!ghost) { + return null; + } + return { y: Number(ghost.dataset.y), x: Number(ghost.dataset.x) }; + }, + [horizontal, vertical], + ); + const scrollStep = useCallback( (e: React.MouseEvent) => { if (!isScrolling || tabularRef.current === null || !sheet) { @@ -105,7 +128,21 @@ export function ScrollHandle({ style, horizontal = 0, vertical = 0, className = const { x, y } = getDestEdge(e); if (live.autofillDraggingTo) { const { y: curY, x: curX } = live.autofillDraggingTo; - dispatch(setAutofillDraggingTo({ y: y === -1 ? curY : y, x: x === -1 ? curX : x })); + // On an auto-expanding sheet the drag scrolls on into ghost rows/cols past the last + // row/col, which have no header cells for getDestEdge to find — target that cell instead. + const ghostPoint = getGhostEdgePoint(e); + // Past the last row/col of an auto-expanding sheet (e.g. the ghosts don't fill the box yet, + // so there's none at the edge), Tabular keeps the target on the last ghost and grows it. + // Snapping it back to the last real row/col here would fight that every frame and stall it. + const r = tabularRef.current.getBoundingClientRect(); + const mode = sheet.autoExpand; + const ownedByGhosts = + !ghostPoint && + (((mode === 'vertical' || mode === 'both') && e.clientY > r.bottom && y >= sheet.numRows) || + ((mode === 'horizontal' || mode === 'both') && e.clientX > r.right && x >= sheet.numCols)); + if (!ownedByGhosts) { + dispatch(setAutofillDraggingTo(ghostPoint ?? { y: y === -1 ? curY : y, x: x === -1 ? curX : x })); + } } else { if (editingAnywhere) { const newArea = zoneToArea({ ...selectingZone, endY: y, endX: x }); @@ -129,6 +166,7 @@ export function ScrollHandle({ style, horizontal = 0, vertical = 0, className = selectingZone, xSheetFocused, getDestEdge, + getGhostEdgePoint, ], ); diff --git a/packages/react-core/src/components/StoreObserver.tsx b/packages/react-core/src/components/StoreObserver.tsx index 1c9359d8..5d9ee39e 100644 --- a/packages/react-core/src/components/StoreObserver.tsx +++ b/packages/react-core/src/components/StoreObserver.tsx @@ -90,15 +90,6 @@ export const StoreObserver: FC = ({ running = false; return; } - // Over the autoExpand ghost cells drawn outside the grid: the pointer is past the edge, but - // the ghost cell itself is the target (its own mouseenter sets it) — don't edge-scroll. - if ( - s.autofillDraggingTo && - (document.elementFromPoint(cx, cy) as HTMLElement | null)?.closest('.gs-ghost-layer') - ) { - raf = requestAnimationFrame(tick); - return; - } const r = el.getBoundingClientRect(); const dy = cy > r.bottom - EDGE ? SPEED : cy < r.top + EDGE ? -SPEED : 0; const dx = cx > r.right - EDGE ? SPEED : cx < r.left + EDGE ? -SPEED : 0; @@ -107,8 +98,9 @@ export const StoreObserver: FC = ({ el.scrollLeft += dx; const px = Math.min(Math.max(cx, r.left + 1), r.right - 1); const py = Math.min(Math.max(cy, r.top + 1), r.bottom - 1); + // Ghost cells (autoExpand) past the last row/col carry data-y/x like real cells. const cell = (document.elementFromPoint(px, py) as HTMLElement | null)?.closest( - '.gs-cell', + '.gs-cell, .gs-ghost-cell', ) as HTMLElement | null; if (cell) { const y = Number(cell.dataset.y); diff --git a/packages/react-core/src/components/Tabular.tsx b/packages/react-core/src/components/Tabular.tsx index 8a744a3c..61502a42 100644 --- a/packages/react-core/src/components/Tabular.tsx +++ b/packages/react-core/src/components/Tabular.tsx @@ -1,21 +1,45 @@ -import { useEffect, useContext, useState, useCallback, useMemo } from 'react'; +import { useEffect, useLayoutEffect, useContext, useState, useCallback, useMemo, useRef } from 'react'; import { Cell, type MergeRender } from './Cell'; import { HeaderCellTop } from './HeaderCellTop'; import { HeaderCellLeft } from './HeaderCellLeft'; import { CellStateOverlay } from './CellStateOverlay'; -import { AutofillGhost } from './AutofillGhost'; import { Context } from '../store'; -import { choose, select, setContextMenuPosition } from '../store/actions'; +import { choose, select, setAutofillDraggingTo, setContextMenuPosition } from '../store/actions'; import type { RefPaletteType, Virtualization } from '../types'; -import { virtualize, physicalScrollHeight } from '@gridsheet/web'; +import { + virtualize, + physicalScrollHeight, + getGhostCellSize, + SCROLL_CAP, + range, + x2c, + complementSelectingArea, + zoneToArea, + smartScroll, +} from '@gridsheet/web'; import { p2a, stripAddressAbsolute } from '@gridsheet/web'; import { Lexer, stripSheetName } from '@gridsheet/web'; import { ScrollHandle } from './ScrollHandle'; import { preventSafariBounce } from '@gridsheet/web'; +// Like Handsontable's autoInsertRow: while a fill drag reaches the last (real or provisional) +// row/column — or the pointer is held past the grid — add one provisional ghost row/column every +// GHOST_INTERVAL_MS. Ghosts are display-only (no sheet change, no history); releasing the fill +// grows the sheet up to the reached row/column in one undo step (see Autofill), and any unreached +// ghosts simply disappear. +const GHOST_INTERVAL_MS = 200; +// The further past the edge the pointer is, the faster ghosts are added: the interval shrinks +// by one step per GHOST_SPEEDUP_PX of distance, down to GHOST_MIN_INTERVAL_MS. +const GHOST_SPEEDUP_PX = 24; +const GHOST_MIN_INTERVAL_MS = 20; +const ghostInterval = (distance: number) => + Math.max(GHOST_MIN_INTERVAL_MS, GHOST_INTERVAL_MS / (1 + Math.max(0, distance) / GHOST_SPEEDUP_PX)); + +const roomFor = (limit: number, current: number) => (limit === -1 ? Infinity : Math.max(0, limit - current)); + export const Tabular = () => { const [palette, setPalette] = useState({}); const { store, dispatch } = useContext(Context); @@ -33,11 +57,147 @@ export const Tabular = () => { leftHeaderSelecting, topHeaderSelecting, contextMenu, + autofillDraggingTo, + selectingZone, } = store; const sheet = sheetReactive.current; const [virtualized, setVirtualized] = useState(null); + // autoExpand: provisional ghost rows/cols shown while dragging an autofill (see GHOST_INTERVAL_MS). + const [ghostCount, setGhostCount] = useState({ rows: 0, cols: 0 }); + // Whether the pointer is past the grid content's bottom/right edge during the drag — dragging + // down from the last row never moves the target onto a new row, so this alone must start the + // growth. Measured from the content (not the scroll box), which may sit inside a larger box. + const [pastEdge, setPastEdge] = useState({ bottom: false, right: false }); + // How far past the content's bottom/right edge the pointer is (px); read when scheduling growth. + const pastDistance = useRef({ bottom: 0, right: 0 }); + // Last pointer position during the drag. The content edge moves as ghosts are added or the grid + // scrolls (with the pointer held still), so pastEdge is re-evaluated then too, not only on moves. + const pointerRef = useRef<{ x: number; y: number } | null>(null); + const evalPastEdge = useCallback(() => { + const el = tabularRef.current; + const inner = el?.querySelector(':scope > .gs-tabular-inner'); + const p = pointerRef.current; + if (!el || !inner || !p) { + return; + } + const box = el.getBoundingClientRect(); + const content = inner.getBoundingClientRect(); + const dBottom = p.y - Math.min(content.bottom, box.bottom); + const dRight = p.x - Math.min(content.right, box.right); + pastDistance.current = { bottom: Math.max(0, dBottom), right: Math.max(0, dRight) }; + // Only once scrolled to that edge — before that, edge auto-scroll walks the real rows/cols. + const atBottom = el.scrollTop + el.clientHeight >= el.scrollHeight - 1; + const atRight = el.scrollLeft + el.clientWidth >= el.scrollWidth - 1; + let bottom = dBottom > 0 && atBottom; + let right = dRight > 0 && atRight; + // Past both edges (a corner): follow the dominant direction only. + if (bottom && right) { + bottom = dBottom >= dRight; + right = !bottom; + } + const next = { bottom, right }; + setPastEdge((prev) => (prev.bottom === next.bottom && prev.right === next.right ? prev : next)); + }, []); + const autoExpanding = !!sheet && !!autofillDraggingTo && sheet.autoExpand !== 'none'; + + useEffect(() => { + if (!autoExpanding) { + setGhostCount((c) => (c.rows || c.cols ? { rows: 0, cols: 0 } : c)); + setPastEdge((p) => (p.bottom || p.right ? { bottom: false, right: false } : p)); + return; + } + const onMove = (e: MouseEvent) => { + pointerRef.current = { x: e.clientX, y: e.clientY }; + evalPastEdge(); + }; + const el = tabularRef.current; + window.addEventListener('mousemove', onMove, true); + el?.addEventListener('scroll', evalPastEdge); + return () => { + window.removeEventListener('mousemove', onMove, true); + el?.removeEventListener('scroll', evalPastEdge); + pointerRef.current = null; + }; + }, [autoExpanding]); + // Ghosts were added (the content grew). While growing past an edge, stay pinned to it (the new + // ghost would otherwise sit just out of view and "not scrolled to the edge" would stop growth), + // then re-check whether the pointer is still past the content. + useLayoutEffect(() => { + if (!autoExpanding) { + return; + } + const el = tabularRef.current; + if (el && pastEdge.bottom) { + el.scrollTop = el.scrollHeight; + } + if (el && pastEdge.right) { + el.scrollLeft = el.scrollWidth; + } + evalPastEdge(); + }, [autoExpanding, ghostCount]); + // Keep the drag target in view as ghosts are added past the viewport, so the growth is visible. + useEffect(() => { + if (!autoExpanding || !sheet || !autofillDraggingTo) { + return; + } + if (autofillDraggingTo.y > sheet.numRows || autofillDraggingTo.x > sheet.numCols) { + smartScroll(sheet, tabularRef.current, autofillDraggingTo); + } + }, [autoExpanding, ghostCount, autofillDraggingTo]); + + let growRows = false; + let growCols = false; + if (autoExpanding && sheet && autofillDraggingTo) { + const mode = sheet.autoExpand; + // Grow only while the pointer is past the grid content's edge (in the whitespace of a larger + // box, or outside it) — never while it's over a cell, real or ghost — and the target has + // reached the last (ghost) row/col. A capped (remapped) scroll height can't be extended + // linearly, so very tall sheets get no row ghosts. + growRows = + (mode === 'vertical' || mode === 'both') && + pastEdge.bottom && + sheet.totalHeight <= SCROLL_CAP && + ghostCount.rows < roomFor(sheet.maxNumRows, sheet.numRows) && + autofillDraggingTo.y >= sheet.numRows + ghostCount.rows; + growCols = + (mode === 'horizontal' || mode === 'both') && + pastEdge.right && + ghostCount.cols < roomFor(sheet.maxNumCols, sheet.numCols) && + autofillDraggingTo.x >= sheet.numCols + ghostCount.cols; + } + // Past the content's edge there is no cell under the pointer to target, so keep the target on + // the last (ghost) row/column — the fill then follows the growth. + useEffect(() => { + if (!autoExpanding || !sheet || !autofillDraggingTo || (!pastEdge.bottom && !pastEdge.right)) { + return; + } + const src = complementSelectingArea(zoneToArea(selectingZone), choosing); + const clamp = (v: number, lo: number, hi: number) => Math.min(Math.max(v, lo), hi); + const mode = sheet.autoExpand; + let next = autofillDraggingTo; + if (pastEdge.bottom && (mode === 'vertical' || mode === 'both')) { + next = { y: sheet.numRows + ghostCount.rows, x: clamp(autofillDraggingTo.x, src.left, src.right) }; + } else if (pastEdge.right && (mode === 'horizontal' || mode === 'both')) { + next = { y: clamp(autofillDraggingTo.y, src.top, src.bottom), x: sheet.numCols + ghostCount.cols }; + } + if (next.y !== autofillDraggingTo.y || next.x !== autofillDraggingTo.x) { + dispatch(setAutofillDraggingTo(next)); + } + }, [autoExpanding, pastEdge, ghostCount, autofillDraggingTo]); + + useEffect(() => { + if (!growRows && !growCols) { + return; + } + const t = window.setTimeout( + () => setGhostCount((c) => ({ rows: c.rows + (growRows ? 1 : 0), cols: c.cols + (growCols ? 1 : 0) })), + ghostInterval(growRows ? pastDistance.current.bottom : pastDistance.current.right), + ); + return () => window.clearTimeout(t); + }, [growRows, growCols, ghostCount]); + // Mark on .gs-main whether the grid overflows the viewport per axis, so the matrix outer // border hugs the content when it fits (border on the inner) and switches to a fixed // viewport overlay when it scrolls. Runs after every render (so it always catches the @@ -68,6 +228,21 @@ export const Tabular = () => { e.stopPropagation(); }, []); + // Dragging an autofill onto a ghost cell targets that (not yet existing) cell. + const handleGhostMouseEnter = useCallback( + (e: React.MouseEvent) => { + if (!autofillDraggingTo) { + return; + } + const y = Number(e.currentTarget.dataset.y); + const x = Number(e.currentTarget.dataset.x); + if (y !== autofillDraggingTo.y || x !== autofillDraggingTo.x) { + dispatch(setAutofillDraggingTo({ y, x })); + } + }, + [autofillDraggingTo], + ); + const handleScroll = useCallback( (e: React.UIEvent) => { if (sheet) { @@ -220,6 +395,21 @@ export const Tabular = () => { return null; } + const ghostSize = getGhostCellSize(sheet); + const ghostHeight = ghostCount.rows * ghostSize.height; + const ghostWidth = ghostCount.cols * ghostSize.width; + const scrollHeight = physicalScrollHeight(sheet); + const ghostXs = ghostCount.cols > 0 ? range(sheet.numCols + 1, sheet.numCols + ghostCount.cols) : []; + // Ghost rows follow the last row, so they only render once the rendered window reaches the + // bottom (offset-based, so trailing filtered — zero-height — rows don't hide them). + const lastRendered = virtualized?.ys?.[virtualized.ys.length - 1]; + const lastRowRendered = lastRendered != null && sheet.getOffsetTop(lastRendered + 1) >= sheet.totalHeight; + const ghostYs = + ghostCount.rows > 0 && lastRowRendered ? range(sheet.numRows + 1, sheet.numRows + ghostCount.rows) : []; + const ghostCell = (y: number, x: number) => ( + + ); + return ( <>
{
@@ -296,6 +487,15 @@ export const Tabular = () => { className="gs-adjuster gs-adjuster-horizontal gs-adjuster-horizontal-right" style={{ width: virtualized?.adjuster?.right }} > + {ghostXs.map((x) => ( + +
{x2c(x)}
+ + ))} @@ -308,6 +508,9 @@ export const Tabular = () => { {virtualized?.xs?.map((x) => )} + {ghostXs.map((x) => ( + + ))} @@ -319,14 +522,28 @@ export const Tabular = () => { {virtualized?.xs?.map((x) => )} + {ghostXs.map((x) => ghostCell(y, x))} ); })} + {/* autoExpand ghost rows: shown past the last row only while an autofill is dragged. */} + {ghostYs.map((y) => ( + + +
+ {y} +
+ + + {virtualized?.xs?.map((x) => ghostCell(y, x))} + + {ghostXs.map((x) => ghostCell(y, x))} + + ))}
- ); }; diff --git a/packages/react-core/src/store/actions.ts b/packages/react-core/src/store/actions.ts index 26060ba6..664d360a 100644 --- a/packages/react-core/src/store/actions.ts +++ b/packages/react-core/src/store/actions.ts @@ -260,6 +260,8 @@ class SubmitAutofillAction extends CoreAction { mutation = true; reduce(store: StoreType, payload: T): StoreWithCallback { try { + const before = store.sheetReactive.current; + const sizeBefore = { numRows: before?.numRows ?? 0, numCols: before?.numCols ?? 0 }; const autofill = new Autofill(store, payload); const sheet = autofill.applied; const selectingZone = areaToZone(autofill.wholeArea); @@ -279,7 +281,10 @@ class SubmitAutofillAction extends CoreAction { // right after a fill. Restore focus after the re-render. return { ...result, - callback: (next: StoreType) => requestAnimationFrame(() => focus(next.editorRef.current)), + callback: (next: StoreType) => { + requestAnimationFrame(() => focus(next.editorRef.current)); + revealGrowth(store, sheet, sizeBefore, selectingZone); + }, }; } catch (e) { // The fill may fail (e.g. a target beyond the sheet). Never leave @@ -418,8 +423,8 @@ class CutAction extends CoreAction { } export const cut = new CutAction().bind(); -// When an autoExpand paste grew the sheet, the new rows/cols land off-screen (the viewport -// keeps its size), so the growth would be invisible. Scroll the pasted range's far corner +// When an autoExpand paste/autofill grew the sheet, the new rows/cols land off-screen (the viewport +// keeps its size), so the growth would be invisible. Scroll the written range's far corner // into view — after the re-render, so the enlarged scroll area exists. const revealGrowth = (store: StoreType, sheet: Sheet, before: { numRows: number; numCols: number }, zone: ZoneType) => { if (sheet.numRows <= before.numRows && sheet.numCols <= before.numCols) { diff --git a/packages/storybook/stories/restriction/autoExpand.stories.tsx b/packages/storybook/stories/restriction/autoExpand.stories.tsx index 41737de6..b680c56e 100644 --- a/packages/storybook/stories/restriction/autoExpand.stories.tsx +++ b/packages/storybook/stories/restriction/autoExpand.stories.tsx @@ -13,7 +13,7 @@ const DESCRIPTION = [ '## How it works', "1. `'none'` (default) clips the overflow; `'vertical'` appends rows; `'horizontal'` appends columns; `'both'` appends either.", '2. While dragging the autofill handle, ghost rows/columns appear past the edge so the drag can reach cells that do not exist yet.', - '3. Growth is capped by `limits.maxRows` / `limits.maxCols` (here 12 rows × 8 columns).', + '3. Growth is capped by `limits.maxRows` / `limits.maxCols` (here 1000 rows × 100 columns).', '4. The added rows/columns and the write undo together in a single step.', '5. The sheet is resizable (`sheetResize: both`) — drag its bottom-right corner to see the grown rows/columns; `matrixAlignment: both` keeps the grid centered.', ].join('\n\n'); @@ -35,7 +35,7 @@ const AutoExpandComponent: React.FC = () => { 0) { + boundaryLeft = Math.max(sheet.numCols - OVERSCAN_X, 1); + } // Rows: binary-search the boundaries instead of accumulating heights from row 1. // The old linear scan was O(last-visible-row-index), so scrolling near the bottom // of a tall sheet cost O(numRows) per scroll event (~38ms at 1M rows). getOffsetTop(y) @@ -144,7 +149,10 @@ export const virtualize = (sheet: Sheet, e: HTMLDivElement | null): Virtualizati // First row whose bottom edge passes the viewport top / bottom (binarySearch returns // numRows + 1 when none does, i.e. scrolled past all content / content shorter than view). const topIdx = binarySearch(1, numRows, (y) => cumHeightThrough(y) > top, true); - boundaryTop = topIdx > numRows ? 0 : Math.max(topIdx - OVERSCAN_Y, 1); + // Scrolled past the last row (into autoExpand ghost rows): keep the trailing rows rendered so + // the table — and the ghost rows appended after them — stay in place. + boundaryTop = + topIdx > numRows ? (numRows > 0 ? Math.max(numRows - OVERSCAN_Y, 1) : 0) : Math.max(topIdx - OVERSCAN_Y, 1); // Remap only: the visible block is placed at physical offset adjTop = physTop - top + // before.height (see below). Near the top of a tall (capped) sheet there isn't enough // physical room above the scroll position for the full top overscan, so adjTop would go diff --git a/packages/web/src/styles/minified.ts b/packages/web/src/styles/minified.ts index e426c68c..2f576a7c 100644 --- a/packages/web/src/styles/minified.ts +++ b/packages/web/src/styles/minified.ts @@ -1,3 +1,3 @@ // pnpm generate-style -export const LAST_MODIFIED = 1791139181; -export const CSS = `.gs-root1{display:inline-block;position:relative;border-spacing:0;width:fit-content;max-width:100%;overflow:auto;font-family:"SF Pro Text","SF Pro Icons","Helvetica Neue",Helvetica,Arial,Meiryo,sans-serif;visibility:hidden;opacity:0}.gs-root1.gs-initialized{visibility:visible;opacity:1;transition:opacity .2s ease-in-out}.gs-root1 .gs-main{flex:1;max-width:100%;overflow:hidden;position:relative;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box}.gs-root1 .gs-resizing{width:100%;height:100%;position:absolute;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 8%,transparent);top:0;left:0;z-index:2}.gs-root1 .gs-line-horizontal{width:100%}.gs-root1 .gs-line-vertical{height:100%}.gs-root1 .gs-line{position:relative;top:0;left:0;border:dotted 1px var(--gs-accent,#2563eb);box-sizing:border-box}.gs-root1 .gs-line span{font-size:10px;padding:3px;background-color:var(--gs-accent,#2563eb);color:#fff;margin:0;position:absolute;top:0;left:0}.gs-root1 .gs-scroll-handle{width:100%;height:100%;cursor:cell}.gs-hidden{visibility:hidden;position:absolute;top:0;left:0;width:0;height:0;overflow:hidden;pointer-events:none;z-index:-1}.gs-fixed{position:fixed;top:0;left:0;z-index:1}:where(.gs-root1[data-mode=light],.gs-editor[data-mode=light]){--gs-fg:#1f2328;--gs-muted-fg:#6b7280;--gs-border:#e3e6ea;--gs-bg:rgba(128, 128, 128, 0.07);--gs-canvas:transparent;--gs-surface:#ffffff;--gs-editor-surface:#ffffff;--gs-header-bg:#f4f5f7;--gs-header-fg:#59616b;--gs-accent:#2563eb}.gs-root1{background-color:var(--gs-bg);color:var(--gs-fg)}.gs-root1 .gs-main{background-color:var(--gs-canvas)}.gs-root1 .gs-tabular{background-color:var(--gs-canvas)}.gs-root1 .gs-sheet-body-data{background-color:var(--gs-surface)}.gs-root1 .gs-formula-bar{background-color:var(--gs-header-bg)}.gs-root1 .gs-formula-bar-editor-inner{color:var(--gs-fg)}.gs-root1 .gs-cell{border:solid 1px var(--gs-border)}.gs-root1 .gs-adjuster{background-color:var(--gs-border)}.gs-root1 .gs-tabular-inner{background-color:var(--gs-border)}.gs-root1 .gs-large-editor textarea{color:var(--gs-fg);caret-color:var(--gs-fg)}.gs-root1 .gs-th{background-color:var(--gs-header-bg);color:var(--gs-header-fg)}.gs-root1 .gs-th-top{border-left:solid 1px var(--gs-border)}.gs-root1 .gs-th-top .gs-th-inner{border-top:solid var(--gs-mx-bt,1px) var(--gs-border)}.gs-root1 .gs-th-left{border-top:solid 1px var(--gs-border)}.gs-root1 .gs-th-left .gs-th-inner{border-left:solid var(--gs-mx-bl,1px) var(--gs-border)}.gs-root1 .gs-search-bar{color:color-mix(in srgb,var(--gs-fg) 40%,transparent)}.gs-root1 .gs-search-bar textarea{color:var(--gs-fg);caret-color:var(--gs-fg)}.gs-editor.gs-editing textarea{caret-color:var(--gs-fg)}.gs-editor.gs-editing .gs-editor-hl{background-color:var(--gs-editor-surface);color:var(--gs-fg)}.gs-editor .gs-editor-options{color:var(--gs-fg);background-color:var(--gs-editor-surface);border:solid 1px var(--gs-border)}:where(.gs-root1[data-mode=dark],.gs-editor[data-mode=dark]){--gs-fg:#e4e6e9;--gs-muted-fg:#8b9096;--gs-border:#2c2f34;--gs-bg:rgba(128, 128, 128, 0.07);--gs-canvas:transparent;--gs-surface:#1c1e21;--gs-editor-surface:#1c1e21;--gs-header-bg:#212327;--gs-header-fg:#a6abb2;--gs-accent:#3b82f6}:where(.gs-root1[data-mode=auto],.gs-editor[data-mode=auto]){--gs-fg:#1f2328;--gs-muted-fg:#6b7280;--gs-border:#e3e6ea;--gs-bg:rgba(128, 128, 128, 0.07);--gs-canvas:transparent;--gs-surface:#ffffff;--gs-editor-surface:#ffffff;--gs-header-bg:#f4f5f7;--gs-header-fg:#59616b;--gs-accent:#2563eb}@media (prefers-color-scheme:dark){:where(.gs-root1[data-mode=auto],.gs-editor[data-mode=auto]){--gs-fg:#e4e6e9;--gs-muted-fg:#8b9096;--gs-border:#2c2f34;--gs-bg:rgba(128, 128, 128, 0.07);--gs-canvas:transparent;--gs-surface:#1c1e21;--gs-editor-surface:#1c1e21;--gs-header-bg:#212327;--gs-header-fg:#a6abb2;--gs-accent:#3b82f6}}:where(.gs-root1[data-mode=inherit-light],.gs-editor[data-mode=inherit-light]){--gs-fg:#1f2328;--gs-muted-fg:#6b7280;--gs-border:#e3e6ea;--gs-bg:rgba(128, 128, 128, 0.07);--gs-surface:#ffffff;--gs-editor-surface:#ffffff;--gs-header-bg:#f4f5f7;--gs-header-fg:#59616b;--gs-accent:#2563eb;--gs-bg:transparent;--gs-canvas:transparent;--gs-surface:transparent;--gs-header-bg:transparent}:where(.gs-root1[data-mode=inherit-dark],.gs-editor[data-mode=inherit-dark]){--gs-fg:#e4e6e9;--gs-muted-fg:#8b9096;--gs-border:#2c2f34;--gs-bg:rgba(128, 128, 128, 0.07);--gs-surface:#1c1e21;--gs-editor-surface:#1c1e21;--gs-header-bg:#212327;--gs-header-fg:#a6abb2;--gs-accent:#3b82f6;--gs-bg:transparent;--gs-canvas:transparent;--gs-surface:transparent;--gs-header-bg:transparent}.gs-root1[data-mode=inherit-dark] .gs-adjuster,.gs-root1[data-mode=inherit-dark] .gs-tabular-inner,.gs-root1[data-mode=inherit-light] .gs-adjuster,.gs-root1[data-mode=inherit-light] .gs-tabular-inner{background-color:transparent}.gs-root1[data-mode=inherit-light] .gs-th{background-color:rgba(128,128,128,.1);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}.gs-root1[data-mode=inherit-dark] .gs-th{background-color:rgba(128,128,128,.1);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}.gs-root1[data-gridlines=horizontal] .gs-cell{border-left-color:transparent;border-right-color:transparent}.gs-root1[data-gridlines=none] .gs-cell{border-color:transparent}.gs-root1[data-density=comfortable] .gs-cell-rendered{padding:0 10px}.gs-cell{transition:border-color .2s ease;padding:0;margin:0;box-sizing:border-box;position:relative;font-size:13px;letter-spacing:1px;line-height:24px;cursor:cell;user-select:none;-webkit-user-select:none;-moz-user-select:none}.gs-cell.gs-copying textarea:focus{outline:solid 1px var(--gs-accent,#2563eb)}.gs-cell.gs-selecting{z-index:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 7%,transparent)}.gs-cell.gs-selecting .gs-cell-label{display:block}.gs-cell.gs-choosing{margin-top:-1px;margin-left:-1px;z-index:1}.gs-cell.gs-choosing.gs-editing{color:transparent}.gs-cell.gs-choosing .gs-cell-label{display:block}.gs-cell.gs-pending .gs-cell-rendered{position:relative;overflow:hidden}.gs-cell.gs-pending .gs-cell-rendered::after{content:'';position:absolute;bottom:0;left:0;height:4px;width:40%;border-radius:1px;background:color-mix(in srgb,var(--gs-accent,#2563eb) 65%,transparent);animation:gs-pending-slide 1.4s ease-in-out infinite}.gs-cell .gs-formula-error-triangle{position:absolute;top:0;right:0;border-top:4px solid rgba(200,0,0,.9);border-right:4px solid rgba(200,0,0,.9);border-bottom:4px solid transparent;border-left:4px solid transparent;z-index:2;cursor:help}.gs-cell .gs-cell-label{font-size:10px;font-weight:500;font-style:normal;font-family:inherit;letter-spacing:.2px;line-height:1.4;position:absolute;top:0;right:0;background-color:var(--gs-accent,#2563eb);color:#fff;padding:1px 5px;border-bottom-left-radius:4px;display:none;opacity:.92}.gs-cell .gs-cell-inner-wrap{width:100%;height:100%;position:absolute;top:0;left:0}.gs-cell .gs-cell-inner{width:100%;height:100%;overflow:hidden;display:flex;box-sizing:border-box;border:none!important}.gs-cell .gs-cell-rendered{overflow:hidden;white-space:pre-wrap;cursor:cell;word-wrap:break-word;word-break:break-all;padding:0 6px;width:100%;height:100%}.gs-cell .gs-cell-rendered>*{position:relative}.gs-cell .gs-cell-rendered>.backface{z-index:0}.gs-cell .gs-autofill-drag{background-color:var(--gs-accent,#2563eb);position:absolute;width:7px;height:7px;bottom:0;right:0;cursor:crosshair;z-index:1}.gs-cell.gs-merged-host{z-index:1}.gs-cell.gs-merged-host.gs-selecting{background-color:transparent}.gs-cell.gs-merged-host.gs-selecting .gs-cell-inner-wrap{background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 7%,transparent)}.gs-cell.gs-merged-covered{z-index:0}.gs-th[data-x="1"] .gs-th-inner-wrap{border-left:none}.gs-th[data-y="1"] .gs-th-inner-wrap{border-top:none}.gs-formula-error-tooltip{position:fixed;background-color:rgba(35,8,8,.94);color:#fff;padding:6px 10px;border-radius:4px;border-left:3px solid rgba(220,50,50,.8);font-size:12px;line-height:1.5;max-width:260px;white-space:pre-wrap;word-break:break-word;box-shadow:0 3px 10px rgba(0,0,0,.4);z-index:100;pointer-events:none;letter-spacing:.3px}.gs-menu-modal{width:100%;height:100vh;z-index:12}.gs-label-input-label{font-size:13px;letter-spacing:1px}.gs-menu-divider{background-color:#aaa;padding:0;margin:5px 0;height:1px;list-style-type:none}.gs-menu-btn{position:absolute;background-color:rgba(128,128,128,.3);border:1px solid #ccc;border-radius:50%;cursor:pointer;font-size:12px;font-weight:700;line-height:1;color:#888;width:18px;height:18px;padding:0;display:flex;align-items:center;justify-content:center;opacity:0;transition:opacity .15s ease;z-index:2}.gs-context-menu{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;opacity:.9;transition:opacity .15s ease}.gs-context-menu:hover{opacity:1}.gs-context-menu .gs-menu-items{color:#555;margin:0;padding:0;min-width:250px}.gs-menu-item{padding:5px 10px;list-style-type:none;display:flex}.gs-menu-item.gs-enabled{cursor:pointer}.gs-menu-item.gs-enabled:hover{background-color:#eee}.gs-menu-item.gs-disabled{opacity:.5;cursor:not-allowed}.gs-menu-item .gs-menu-name{font-size:13px;letter-spacing:1px;flex:1}.gs-submenu-parent{position:relative;align-items:center}.gs-submenu-parent .gs-submenu-arrow{margin-left:8px;font-size:11px;opacity:.6}.gs-submenu-flyout{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;opacity:.9;transition:opacity .15s ease;min-width:200px;margin:0;color:#555;opacity:1;list-style-type:none}.gs-submenu-flyout:hover{opacity:1}.gs-menu-shortcut{font-size:10px;line-height:20px;color:#999}.gs-menu-shortcut:before{content:"( "}.gs-menu-shortcut:after{content:" )"}.gs-menu-shortcut .gs-menu-underline{text-decoration:underline}.gs-column-menu{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;opacity:.9;transition:opacity .15s ease}.gs-column-menu:hover{opacity:1}.gs-column-menu ul{color:#555;margin:0;padding:0;min-width:200px}.gs-column-menu .gs-column-menu-sort{align-items:center}.gs-column-menu .gs-column-menu-sort .gs-sort-buttons{display:flex;gap:4px;margin-left:auto}.gs-column-menu .gs-column-menu-sort .gs-sort-btn{font-size:12px;padding:4px 8px;border:1px solid transparent;border-radius:3px;background-color:rgba(180,180,180,.1);cursor:pointer;color:#555;font-weight:700;letter-spacing:.5px}.gs-column-menu .gs-column-menu-sort .gs-sort-btn:hover:not(:disabled){border-color:#555}.gs-column-menu .gs-column-menu-sort .gs-sort-btn:disabled{opacity:.5;cursor:not-allowed}.gs-column-menu .gs-column-menu-label{padding:5px 10px}.gs-column-menu .gs-label-input-row{display:flex;gap:4px;align-items:center}.gs-column-menu .gs-label-input{flex:1;font-size:13px;padding:4px 6px;border:none;border-bottom:1px solid #ccc;border-radius:0;outline:0;min-width:0;width:100px;background-color:transparent;box-shadow:none}.gs-column-menu .gs-label-input:focus{border-bottom-color:var(--gs-accent,#2563eb);outline:0;box-shadow:none}.gs-column-menu .gs-label-apply-btn{font-size:12px;padding:4px 8px;border:1px solid transparent;border-radius:3px;background-color:rgba(180,180,180,.1);cursor:pointer;color:#555;font-weight:700;letter-spacing:.5px}.gs-column-menu .gs-label-apply-btn:hover:not(:disabled){border-color:#555}.gs-column-menu .gs-label-apply-btn:disabled{opacity:.5;cursor:not-allowed}.gs-column-menu .gs-column-menu-filter{padding:5px 10px;list-style-type:none;font-size:13px}.gs-column-menu .gs-filter-header{display:flex;align-items:center;gap:8px}.gs-column-menu .gs-filter-header .gs-filter-add-btn{font-size:12px;padding:3px 9px;border:1px solid transparent;border-radius:3px;background-color:rgba(180,180,180,.1);cursor:pointer;color:#555;letter-spacing:1px}.gs-column-menu .gs-filter-header .gs-filter-add-btn:hover{border-color:#555}.gs-column-menu .gs-filter-mode-toggle{display:flex;gap:6px;margin-left:auto}.gs-column-menu .gs-filter-mode-toggle label{display:flex;align-items:center;gap:3px;font-size:11px;font-weight:700;letter-spacing:.5px;color:#888;cursor:pointer;user-select:none}.gs-column-menu .gs-filter-mode-toggle label input[type=radio]{margin:0;cursor:pointer}.gs-column-menu .gs-filter-mode-toggle label.gs-active{color:var(--gs-accent,#2563eb)}.gs-column-menu .gs-filter-mode-toggle.gs-disabled{opacity:.4;pointer-events:none}.gs-column-menu .gs-filter-conditions{display:flex;flex-direction:column;gap:5px;margin-top:6px;max-height:200px;overflow-y:auto}.gs-column-menu .gs-filter-condition-row{display:flex;gap:4px;align-items:normal}.gs-column-menu .gs-filter-method-select{font-size:12px;padding:4px 4px;border:none;border-bottom:1px solid #ccc;border-radius:0;outline:0;background-color:#fff;box-shadow:none;min-width:40px;max-width:80px;cursor:pointer}.gs-column-menu .gs-filter-method-select:focus{border-bottom-color:var(--gs-accent,#2563eb);outline:0;box-shadow:none}.gs-column-menu .gs-filter-value-input{flex:1;font-size:13px;padding:4px 6px;border:none;border-bottom:1px solid #ccc;border-radius:0;outline:0;min-width:0;width:80px;background-color:transparent;box-shadow:none}.gs-column-menu .gs-filter-value-input:focus{border-bottom-color:var(--gs-accent,#2563eb);outline:0;box-shadow:none}.gs-column-menu .gs-filter-remove-btn{font-size:12px;padding:0;border:none;border-radius:3px;background-color:transparent;cursor:pointer;color:#999;line-height:1;flex-shrink:0}.gs-column-menu .gs-filter-remove-btn:hover{color:#c33}.gs-column-menu .gs-filter-actions{display:flex;gap:4px;margin-top:10px;align-items:center}.gs-column-menu .gs-filter-actions .gs-filter-reset-all-btn{font-size:12px;padding:3px 9px;border:1px solid transparent;border-radius:3px;background-color:transparent;cursor:pointer;color:#c33;font-weight:700;letter-spacing:1px}.gs-column-menu .gs-filter-actions .gs-filter-reset-all-btn:hover{border-color:#c33}.gs-column-menu .gs-filter-actions .gs-filter-actions-right{display:flex;gap:4px;margin-left:auto}.gs-column-menu .gs-filter-actions .gs-filter-reset-btn{font-size:12px;padding:3px 9px;border:1px solid transparent;border-radius:3px;background-color:transparent;cursor:pointer;color:#e08000;font-weight:700;letter-spacing:1px}.gs-column-menu .gs-filter-actions .gs-filter-reset-btn:hover{border-color:#e08000}.gs-column-menu .gs-filter-actions .gs-filter-apply-btn{font-size:12px;padding:3px 6px;border:1px solid transparent;border-radius:3px;background-color:transparent;color:var(--gs-accent,#2563eb);cursor:pointer;font-weight:700;letter-spacing:1px}.gs-column-menu .gs-filter-actions .gs-filter-apply-btn:hover{border-color:var(--gs-accent,#2563eb)}.gs-column-menu-waiting{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:20px 30px;gap:12px;min-width:180px}.gs-column-menu-waiting .gs-waiting-message{font-size:13px;font-weight:700;color:#555;letter-spacing:.5px}.gs-column-menu-waiting .gs-waiting-spinner{width:24px;height:24px;border:3px solid #e0e0e0;border-top-color:var(--gs-accent,#2563eb);border-radius:50%;animation:spin .8s linear infinite}.gs-column-menu-waiting .gs-waiting-cancel-btn{font-size:12px;padding:4px 18px;border:1px solid #c33;border-radius:3px;background-color:transparent;color:#c33;cursor:pointer;font-weight:700;letter-spacing:1px}.gs-column-menu-waiting .gs-waiting-cancel-btn:hover{background-color:#c33;color:#fff}.gs-column-menu-btn{right:4px;top:50%;transform:translateY(-50%)}.gs-column-menu-btn.gs-filtered{opacity:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);border-color:var(--gs-accent,#2563eb);color:var(--gs-accent,#2563eb)}.gs-column-menu-btn.gs-active{opacity:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 18%,transparent);border-color:var(--gs-accent,#2563eb);color:var(--gs-accent,#2563eb)}.gs-th-top:hover .gs-column-menu-btn{opacity:1}.gs-row-menu{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;opacity:.9;transition:opacity .15s ease}.gs-row-menu:hover{opacity:1}.gs-row-menu ul{color:#555;margin:0;padding:0;min-width:200px}.gs-row-fixed-toggle{display:flex;align-items:center;gap:6px}.gs-row-fixed-check{font-size:12px;width:14px;text-align:center;color:transparent}.gs-row-fixed-check.gs-row-fixed-active{color:var(--gs-accent,#2563eb)}.gs-row-menu-btn{top:50%;transform:translateY(-50%);right:2px}.gs-row-menu-btn.gs-active{opacity:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 18%,transparent);border-color:var(--gs-accent,#2563eb);color:var(--gs-accent,#2563eb)}.gs-th-left:hover .gs-row-menu-btn{opacity:1}.gs-corner-menu-btn{bottom:2px;right:2px}.gs-corner-menu-btn:hover{opacity:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 18%,transparent);border-color:var(--gs-accent,#2563eb);color:var(--gs-accent,#2563eb)}.gs-th-left.gs-th-top:hover .gs-corner-menu-btn{opacity:1}.gs-editor-hl{padding:0 2px!important;position:absolute;font-family:monospace,Arial;font-size:12px;line-height:24px;letter-spacing:1px}.gs-formula-bar-editor-inner{position:relative;flex:1;min-width:0;display:flex;align-items:center}.gs-editor{opacity:0;z-index:-1}.gs-editor .gs-editor-inner{position:relative}.gs-editor .gs-editor-hl{box-sizing:content-box;border:solid 2px var(--gs-accent,#2563eb);margin:-2px -1px}.gs-editor textarea{width:100%;padding:0 2px!important;position:absolute;font-size:12px;font-family:monospace,Arial;line-height:24px;letter-spacing:1px;top:0;left:0;border:none;outline:0;background-color:transparent;color:transparent;resize:none;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;overflow:hidden;cursor:default;white-space:pre;height:auto}.gs-editor.gs-editing{z-index:11;opacity:1}.gs-editor.gs-editing .gs-cell-label{pointer-events:none;font-family:inherit;font-weight:500;position:absolute;top:0;right:0;margin-top:-17px;margin-right:-2px;padding:1px 5px;border-top-left-radius:4px;border-top-right-radius:4px;font-size:10px;background-color:var(--gs-accent,#2563eb);color:#fff;z-index:1}.gs-formula-bar{width:100%;position:relative;display:flex;align-items:stretch;box-sizing:border-box;border-style:solid;border-color:var(--gs-border,#e3e6ea);border-width:var(--gs-fb-bt,1px) var(--gs-fb-br,1px) var(--gs-fb-bb,1px) var(--gs-fb-bl,1px);padding:3px 6px;gap:6px}.gs-formula-bar .gs-selecting-address{display:flex;align-items:center;justify-content:center;min-width:38px;padding:0 4px;color:var(--gs-muted-fg,#6b7280);font-size:12px;font-variant-numeric:tabular-nums;text-align:center}.gs-formula-bar[data-spill=true]{background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 6%,var(--gs-header-bg,#f4f5f7))}.gs-formula-bar[data-spill=true] .gs-selecting-address{color:var(--gs-accent,#2563eb);font-style:italic}.gs-formula-bar[data-spill=true] .gs-selecting-address::after{content:"\\2196";margin-left:2px;font-style:normal;font-size:9px}.gs-formula-bar .gs-fx{display:flex;align-items:center;justify-content:center;align-self:center;width:26px;height:18px;flex-shrink:0;color:var(--gs-muted-fg,#6b7280);font-style:italic;font-family:inherit;font-weight:400;text-align:center;font-size:13px;letter-spacing:.3px;border-radius:4px;background-color:color-mix(in srgb,var(--gs-fg,#1f2328) 6%,transparent)}.gs-formula-bar .gs-editor-hl{z-index:0;overflow-y:auto;box-sizing:border-box;white-space:pre-wrap;word-break:break-all;text-align:left;line-height:24px}.gs-formula-bar textarea{position:relative;z-index:1;width:100%;vertical-align:bottom;color:transparent;border:none;background-color:transparent;padding:0 2px;box-sizing:border-box;text-align:left;outline:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;font-size:12px;font-family:monospace,Arial;height:24px;line-height:24px;min-height:24px;letter-spacing:1px;resize:vertical;caret-color:var(--gs-fg,#1f2328);white-space:pre-wrap;word-break:break-all}.gs-token-type-INVALID_REF{color:red}.gs-token-type-VALUE.gs-token-entity-type-boolean,.gs-token-type-VALUE.gs-token-entity-type-number{color:#39f}.gs-token-type-VALUE.gs-token-entity-type-string{color:#090}.gs-editor-options{position:fixed;z-index:1000;padding:4px;background:var(--gs-bg,#fff);box-shadow:0 4px 12px rgba(0,0,0,.15);border:1px solid rgba(0,0,0,.1);border-radius:6px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;overflow:visible}.gs-editor-option{position:relative;cursor:pointer;list-style:none;padding:6px 12px;font-size:13px;border-radius:4px;color:#333;margin-bottom:2px}.gs-editor-option-content{display:flex;justify-content:space-between;width:100%;align-items:center}.gs-editor-option-tab{font-size:10px;color:#aaa;margin-left:8px;padding:2px 4px;border:1px solid #ddd;border-radius:3px;background:#f9f9f9}.gs-editor-option:last-child{margin-bottom:0}.gs-editor-option:hover{background-color:#f5f5f5}.gs-editor-option-selected{background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);color:var(--gs-accent,#2563eb);font-weight:500}.gs-editor-option-selected:hover{background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 18%,transparent)}.gs-fn-guide1{position:absolute;top:-4px;left:calc(100% + 8px);background:#fff;border:1px solid rgba(0,0,0,.1);box-shadow:0 4px 16px rgba(0,0,0,.12);border-radius:6px;padding:16px;width:280px;z-index:1000;cursor:default;white-space:normal;color:#333}.gs-fn-guide1-tooltip{margin-bottom:8px;line-height:1.4;font-size:13px}.gs-fn-guide1-example{font-family:monospace;font-weight:600;font-size:13px;margin-bottom:8px;color:#1a1a1a;background:#f5f5f5;padding:6px 8px;border-radius:4px;border:1px solid #eee;display:flex;align-items:center;gap:6px;flex-wrap:wrap}.gs-fn-guide1-desc{font-size:13px;color:#555;margin-bottom:12px;line-height:1.4}.gs-fn-guide1-desc p{margin:0 0 6px 0}.gs-fn-guide1-desc p:last-child{margin-bottom:0}.gs-fn-guide1-args{border-top:1px solid #eee;padding-top:10px}.gs-fn-guide1-arg{margin-bottom:6px;line-height:1.4;font-size:12px}.gs-fn-guide1-arg-name{font-weight:600;color:var(--gs-accent,#2563eb)}.gs-fn-guide1-arg-opt{color:#888;font-size:11px}.gs-fn-guide1-arg-iter{font-weight:600;color:var(--gs-accent,#2563eb)}.gs-fn-guide1-arg-type{color:var(--gs-accent,#2563eb);padding:0 4px;background:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);border-radius:3px;font-size:11px;margin:0 4px}.gs-fn-guide1-arg-desc{color:#666}.gs-fn-guide-category{position:absolute;top:-11px;right:8px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;font-size:11px;font-weight:600;letter-spacing:.5px;text-transform:uppercase;padding:2px 7px;border-radius:4px;background:#e8eaf6;color:#3949ab;border:1px solid #c5cae9;white-space:nowrap}.gs-fn-guide-category.gs-fn-guide-category-math{background:#e3f2fd;color:#1565c0;border-color:#bbdefb}.gs-fn-guide-category.gs-fn-guide-category-statistics{background:#e8f5e9;color:#2e7d32;border-color:#c8e6c9}.gs-fn-guide-category.gs-fn-guide-category-text{background:#fff8e1;color:#f57f17;border-color:#ffecb3}.gs-fn-guide-category.gs-fn-guide-category-time{background:#fce4ec;color:#880e4f;border-color:#f8bbd0}.gs-fn-guide-category.gs-fn-guide-category-lookup{background:#f3e5f5;color:#6a1b9a;border-color:#e1bee7}.gs-fn-guide-category.gs-fn-guide-category-logical{background:#e0f2f1;color:#00695c;border-color:#b2dfdb}.gs-fn-guide-category.gs-fn-guide-category-information{background:#e0f7fa;color:#006064;border-color:#b2ebf2}.gs-fn-guide-category.gs-fn-guide-category-finance{background:#fff3e0;color:#e65100;border-color:#ffe0b2}.gs-fn-guide-category.gs-fn-guide-category-engineering{background:#efebe9;color:#4e342e;border-color:#d7ccc8}.gs-fn-guide-category.gs-fn-guide-category-ai{background:#e8eaf6;color:#3949ab;border-color:#c5cae9}.gs-fn-guide-category.gs-fn-guide-category-other{background:#f5f5f5;color:#616161;border-color:#e0e0e0}.gs-editor-portal{display:contents}.gs-editor-portal[data-mode=dark] .gs-editor-options,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-options,.gs-editor[data-mode=dark] .gs-editor-options,.gs-editor[data-mode=inherit-dark] .gs-editor-options{background:#252526;border-color:#454545;box-shadow:0 4px 12px rgba(0,0,0,.5)}.gs-editor-portal[data-mode=dark] .gs-editor-option,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option,.gs-editor[data-mode=dark] .gs-editor-option,.gs-editor[data-mode=inherit-dark] .gs-editor-option{color:#ccc}.gs-editor-portal[data-mode=dark] .gs-editor-option:hover,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option:hover,.gs-editor[data-mode=dark] .gs-editor-option:hover,.gs-editor[data-mode=inherit-dark] .gs-editor-option:hover{background-color:#333}.gs-editor-portal[data-mode=dark] .gs-editor-option-selected,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option-selected,.gs-editor[data-mode=dark] .gs-editor-option-selected,.gs-editor[data-mode=inherit-dark] .gs-editor-option-selected{background-color:#094771;color:#fff}.gs-editor-portal[data-mode=dark] .gs-editor-option-selected:hover,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option-selected:hover,.gs-editor[data-mode=dark] .gs-editor-option-selected:hover,.gs-editor[data-mode=inherit-dark] .gs-editor-option-selected:hover{background-color:#0d5a8f}.gs-editor-portal[data-mode=dark] .gs-editor-option-tab,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option-tab,.gs-editor[data-mode=dark] .gs-editor-option-tab,.gs-editor[data-mode=inherit-dark] .gs-editor-option-tab{color:#777;background:#333;border-color:#444}.gs-editor-portal[data-mode=dark] .gs-fn-guide1,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1,.gs-editor[data-mode=dark] .gs-fn-guide1,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1{background:#252526;border-color:#454545;color:#ccc}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-example,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-example,.gs-editor[data-mode=dark] .gs-fn-guide1-example,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-example{background:#1e1e1e;border-color:#333;color:#d4d4d4}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-desc,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-desc,.gs-editor[data-mode=dark] .gs-fn-guide1-desc,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-desc{color:#aaa}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-args,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-args,.gs-editor[data-mode=dark] .gs-fn-guide1-args,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-args{border-color:#333}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-iter,.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-name,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-iter,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-name,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-iter,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-name,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-iter,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-name{color:#4fc1ff}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-opt,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-opt,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-opt,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-opt{color:#777}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-type,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-type,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-type,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-type{background:#094771;color:#4fc1ff}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-desc,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-desc,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-desc,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-desc{color:#999}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category,.gs-editor[data-mode=dark] .gs-fn-guide-category,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category{background:#2a2d3e;color:#7986cb;border-color:#3d4166}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-math,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-math,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-math,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-math{background:#0d2137;color:#64b5f6;border-color:#1a3a5c}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-statistics,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-statistics,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-statistics,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-statistics{background:#0d2218;color:#66bb6a;border-color:#1a3d2a}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-text,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-text,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-text,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-text{background:#2e2200;color:#ffd54f;border-color:#4d3900}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-time,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-time,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-time,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-time{background:#2d0d1e;color:#f48fb1;border-color:#4d1a33}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-lookup,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-lookup,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-lookup,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-lookup{background:#260d33;color:#ce93d8;border-color:#3d1a54}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-logical,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-logical,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-logical,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-logical{background:#0d2421;color:#4db6ac;border-color:#1a3d39}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-information,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-information,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-information,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-information{background:#0d2426;color:#4dd0e1;border-color:#1a3d40}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-finance,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-finance,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-finance,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-finance{background:#2e1500;color:#ffb74d;border-color:#4d2800}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-engineering,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-engineering,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-engineering,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-engineering{background:#1e1714;color:#bcaaa4;border-color:#332c28}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-ai,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-ai,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-ai,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-ai{background:#10142e;color:#7986cb;border-color:#232a52}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-other,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-other,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-other,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-other{background:#1e1e1e;color:#9e9e9e;border-color:#333}.gs-editor-portal[data-mode=dark] .gs-fn-guide2,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2,.gs-editor[data-mode=dark] .gs-fn-guide2,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2{background:#252526;border-color:#454545;box-shadow:0 4px 12px rgba(0,0,0,.5);color:#ccc}.gs-editor-portal[data-mode=dark] .gs-fn-guide2-name,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2-name,.gs-editor[data-mode=dark] .gs-fn-guide2-name,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2-name{color:#dfdbdb;background:#333;border-color:#444}.gs-editor-portal[data-mode=dark] .gs-fn-guide2 .gs-active-arg,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2 .gs-active-arg,.gs-editor[data-mode=dark] .gs-fn-guide2 .gs-active-arg,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2 .gs-active-arg{color:#fff;background-color:#094771}.gs-editor-portal[data-mode=dark] .gs-fn-guide2-arg-type,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2-arg-type,.gs-editor[data-mode=dark] .gs-fn-guide2-arg-type,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2-arg-type{background:#094771;color:#4fc1ff}.gs-editor-portal[data-mode=dark] .gs-fn-guide2-desc,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2-desc,.gs-editor[data-mode=dark] .gs-fn-guide2-desc,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2-desc{color:#aaa;border-top-color:#333}.gs-fn-guide2{position:fixed;left:0;background:#fff;border:1px solid rgba(0,0,0,.1);box-shadow:0 4px 16px rgba(0,0,0,.12);border-radius:6px;padding:12px 16px;width:280px;z-index:1000;cursor:default;white-space:normal;color:#333;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;transition:opacity .1s ease-in-out}.gs-fn-guide2.gs-fn-guide2-hidden{opacity:0!important;pointer-events:none!important}.gs-fn-guide2-name{font-family:monospace;font-weight:700;font-size:13px;color:#1a1a1a;background:#f5f5f5;padding:6px 8px;border-radius:4px;border:1px solid #eee;display:flex;align-items:center;gap:6px;flex-wrap:wrap;width:100%;box-sizing:border-box;margin-bottom:8px}.gs-fn-guide2-args-inline{font-size:13px;font-family:monospace;line-height:1.5;margin-bottom:8px;color:#666}.gs-fn-guide2-args-inline span{transition:all .2s ease-in-out}.gs-fn-guide2 .gs-active-arg{font-weight:700;color:var(--gs-accent,#2563eb);background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);padding:2px 4px;margin:0 -4px;border-radius:4px}.gs-fn-guide2-arg-type{color:var(--gs-accent,#2563eb);padding:0 4px;background:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);border-radius:3px;font-size:11px;margin:0 4px}.gs-fn-guide2-desc{font-size:12px;color:#555;line-height:1.4;border-top:1px solid #eee;padding-top:8px;margin-top:4px}.gs-fn-guide2-desc p{margin:0}.gs-fn-guide2-desc-more{font-style:italic;color:#888;margin-top:4px!important;font-size:11px}.gs-adjuster{padding:0}.gs-table{margin:0}.gs-tabular{overflow:auto;overflow-anchor:none;display:flex;box-sizing:border-box;position:relative}.gs-root1[data-matrix-align=both] .gs-tabular,.gs-root1[data-matrix-align=horizontal] .gs-tabular{justify-content:safe center}.gs-root1[data-matrix-align=both] .gs-tabular,.gs-root1[data-matrix-align=vertical] .gs-tabular{align-items:safe center}.gs-tabular-inner{flex:0 0 auto;position:relative;overflow:hidden;overflow:clip;box-sizing:border-box;border-right:solid var(--gs-mx-br,1px) var(--gs-border,#e3e6ea);border-bottom:solid var(--gs-mx-bb,1px) var(--gs-border,#e3e6ea)}.gs-tabular-inner>table{table-layout:fixed;border-collapse:collapse;border-spacing:0}.gs-ghost-layer{font-size:13px}.gs-ghost-layer .gs-ghost-panel{position:fixed;overflow:hidden;z-index:1000;cursor:crosshair}.gs-ghost-layer .gs-ghost-cell,.gs-ghost-layer .gs-ghost-th{position:absolute;box-sizing:border-box}.gs-ghost-layer .gs-ghost-cell{border:dashed 1px var(--gs-border,#e3e6ea);background-color:color-mix(in srgb,var(--gs-surface,#fff) 70%,transparent)}.gs-ghost-layer .gs-ghost-cell.gs-ghost-target{background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,var(--gs-surface,#fff));border-color:color-mix(in srgb,var(--gs-accent,#2563eb) 45%,transparent)}.gs-ghost-layer .gs-ghost-th{display:flex;align-items:center;justify-content:center;background-color:var(--gs-header-bg,#f6f7f9);color:var(--gs-header-fg,#555);border:dashed 1px var(--gs-border,#e3e6ea);opacity:.75}.gs-main[data-overflow-x=true] .gs-tabular-inner{border-right-width:0}.gs-main[data-overflow-y=true] .gs-tabular-inner{border-bottom-width:0}.gs-main::after{content:'';position:absolute;inset:0;pointer-events:none;z-index:3;border:0 solid var(--gs-border,#e3e6ea)}.gs-main[data-overflow-x=true]::after{border-right-width:var(--gs-mx-br,1px)}.gs-main[data-overflow-y=true]::after{border-bottom-width:var(--gs-mx-bb,1px)}.gs-th{z-index:2;padding:0;position:sticky;font-size:13px;font-weight:400;box-sizing:border-box;vertical-align:top}.gs-th .gs-resizer{position:absolute;border-color:transparent;box-sizing:border-box;z-index:2}.gs-th .gs-resizer:hover{background-color:var(--gs-accent,#2563eb)}.gs-th .gs-resizer.gs-protected{display:none}.gs-th-inner{height:100%;box-sizing:border-box;vertical-align:middle;overflow:hidden;display:flex;align-items:center;justify-content:center}.gs-th-inner-wrap{height:100%;box-sizing:border-box;background-color:transparent}.gs-th-top{top:0;overflow:hidden}.gs-th-top .gs-resizer{top:0;right:0;width:3px;cursor:e-resize}.gs-th-top .gs-resizer.gs-dragging{border-right-style:dotted;height:1000000px!important;cursor:e-resize}.gs-th-left{left:0;overflow:hidden;min-width:30px;border-top:solid 1px var(--gs-border,#e3e6ea)}.gs-th-left .gs-resizer{left:0;bottom:0;height:3px;cursor:n-resize}.gs-th-left .gs-resizer.gs-dragging{border-bottom-style:dotted;width:1000000px!important;cursor:n-resize}.gs-th-top.gs-th-left{top:0;left:0;z-index:3;border:none!important}.gs-th-left.gs-filter-fixed .gs-th-inner::before{content:'‹\\00a0'}.gs-th-left.gs-sort-fixed .gs-th-inner::after{content:'\\00a0›'}.gs-col-addr{position:absolute;top:2px;right:4px;font-size:9px;opacity:.5;line-height:1;letter-spacing:.3px;pointer-events:none}.gs-search-bar{width:100%;display:flex;align-items:center;padding:3px 0;border-top:solid 1px rgba(128,128,128,.3);border-left:solid 1px rgba(128,128,128,.3);border-right:solid 1px rgba(128,128,128,.3);border-bottom:solid 1px rgba(128,128,128,.3);box-sizing:border-box;background-color:rgba(200,50,0,.2)}.gs-search-bar.gs-search-found{background-color:rgba(0,200,100,.2)}.gs-search-bar .gs-search-bar-inner{border-left:solid 1px rgba(128,128,128,.5)}.gs-search-bar .gs-search-bar-icon{border-left:solid 1px rgba(128,128,128,.3);display:flex;align-items:center;justify-content:center;width:30px;flex-shrink:0}.gs-search-bar .gs-search-input-wrapper{flex-grow:1;position:relative;display:flex;align-items:center;height:100%}.gs-search-bar .gs-search-input-ghost{position:absolute;left:2px;right:2px;top:0;bottom:0;pointer-events:none;font-size:12px;font-family:monospace,Arial;line-height:24px;letter-spacing:1px;white-space:pre-wrap;word-break:break-all;color:transparent;overflow:hidden}.gs-search-bar .gs-search-input-ghost .gs-search-ghost-hint{color:#aaa}.gs-search-bar textarea{background-color:transparent;border:none;padding:0 2px;box-sizing:border-box;outline:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;font-size:12px;font-family:monospace,Arial;height:24px;line-height:24px;min-height:24px;letter-spacing:1px;caret-color:rgba(128,128,128);white-space:pre-wrap;word-break:break-all;flex-grow:1;width:100%;resize:none}.gs-search-progress{color:#999;font-size:13px;width:60px;flex-shrink:0;white-space:nowrap;text-align:center}.gs-search-close{cursor:pointer;display:flex;align-items:center;justify-content:center;width:24px;flex-shrink:0}.gs-search-buttons{display:flex;align-items:center;white-space:nowrap;flex-shrink:0}.gs-search-button{display:inline-flex;cursor:pointer;margin:0 2px}.gs-search-button span{display:inline-block;font-size:11px;padding:3px 5px;background-color:rgba(128,128,128,.1);border:1px solid rgba(128,128,128,.3);border-radius:3px;transition:all .15s ease;line-height:1}.gs-search-button span:hover{background-color:rgba(128,128,128,.2)}.gs-search-button span.gs-search-button-on{color:var(--gs-accent,#2563eb);background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 22%,transparent);border-color:var(--gs-accent,#2563eb)}.gs-search-range span{white-space:nowrap;font-family:monospace}@keyframes spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}.gs-loading-overlay{position:absolute;top:0;left:0;right:0;bottom:0;background:color-mix(in srgb,var(--gs-surface,#fff) 70%,transparent);display:flex;align-items:center;justify-content:center;z-index:100;pointer-events:all}.gs-loading-spinner{width:32px;height:32px;border:3px solid color-mix(in srgb,var(--gs-fg,#1f2328) 12%,transparent);border-top-color:var(--gs-accent,#2563eb);border-radius:50%;animation:spin .8s linear infinite}.gs-progress-overlay{position:absolute;top:0;left:0;right:0;bottom:0;z-index:100;pointer-events:all;display:flex;align-items:center;justify-content:center}.gs-progress-box{min-width:240px;padding:16px 18px;border-radius:8px;background:var(--gs-editor-surface,#fff);border:1px solid var(--gs-border,#e3e6ea);box-shadow:0 6px 24px rgba(0,0,0,.28);display:flex;flex-direction:column;gap:10px}.gs-progress-head{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--gs-fg,#1f2328)}.gs-progress-head .gs-loading-spinner{width:15px;height:15px;border-width:2px}.gs-progress-track{height:6px;border-radius:3px;overflow:hidden;background:color-mix(in srgb,var(--gs-fg,#1f2328) 12%,transparent)}.gs-progress-fill{height:100%;border-radius:3px;background:var(--gs-accent,#2563eb);transition:width .1s linear}@keyframes gs-pending-slide{0%{left:-40%}100%{left:100%}}@keyframes gs-pending-pulse{0%{left:0;width:0}50%{left:0;width:100%}100%{left:100%;width:0}}@keyframes gs-flash{0%{opacity:0}20%{opacity:1}100%{opacity:0}}.gs-flash-overlay{position:absolute;inset:0;pointer-events:none;z-index:9999;background:color-mix(in srgb,var(--gs-accent,#2563eb) 15%,transparent);opacity:0}.gs-flash-overlay--active{animation:gs-flash .6s ease-out forwards}`; +export const LAST_MODIFIED = 1791034553; +export const CSS = `.gs-root1{display:inline-block;position:relative;border-spacing:0;width:fit-content;max-width:100%;overflow:auto;font-family:"SF Pro Text","SF Pro Icons","Helvetica Neue",Helvetica,Arial,Meiryo,sans-serif;visibility:hidden;opacity:0}.gs-root1.gs-initialized{visibility:visible;opacity:1;transition:opacity .2s ease-in-out}.gs-root1 .gs-main{flex:1;max-width:100%;overflow:hidden;position:relative;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box}.gs-root1 .gs-resizing{width:100%;height:100%;position:absolute;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 8%,transparent);top:0;left:0;z-index:2}.gs-root1 .gs-line-horizontal{width:100%}.gs-root1 .gs-line-vertical{height:100%}.gs-root1 .gs-line{position:relative;top:0;left:0;border:dotted 1px var(--gs-accent,#2563eb);box-sizing:border-box}.gs-root1 .gs-line span{font-size:10px;padding:3px;background-color:var(--gs-accent,#2563eb);color:#fff;margin:0;position:absolute;top:0;left:0}.gs-root1 .gs-scroll-handle{width:100%;height:100%;cursor:cell}.gs-hidden{visibility:hidden;position:absolute;top:0;left:0;width:0;height:0;overflow:hidden;pointer-events:none;z-index:-1}.gs-fixed{position:fixed;top:0;left:0;z-index:1}:where(.gs-root1[data-mode=light],.gs-editor[data-mode=light]){--gs-fg:#1f2328;--gs-muted-fg:#6b7280;--gs-border:#e3e6ea;--gs-bg:rgba(128, 128, 128, 0.07);--gs-canvas:transparent;--gs-surface:#ffffff;--gs-editor-surface:#ffffff;--gs-header-bg:#f4f5f7;--gs-header-fg:#59616b;--gs-accent:#2563eb}.gs-root1{background-color:var(--gs-bg);color:var(--gs-fg)}.gs-root1 .gs-main{background-color:var(--gs-canvas)}.gs-root1 .gs-tabular{background-color:var(--gs-canvas)}.gs-root1 .gs-sheet-body-data{background-color:var(--gs-surface)}.gs-root1 .gs-formula-bar{background-color:var(--gs-header-bg)}.gs-root1 .gs-formula-bar-editor-inner{color:var(--gs-fg)}.gs-root1 .gs-cell{border:solid 1px var(--gs-border)}.gs-root1 .gs-adjuster{background-color:var(--gs-border)}.gs-root1 .gs-tabular-inner{background-color:var(--gs-border)}.gs-root1 .gs-large-editor textarea{color:var(--gs-fg);caret-color:var(--gs-fg)}.gs-root1 .gs-th{background-color:var(--gs-header-bg);color:var(--gs-header-fg)}.gs-root1 .gs-th-top{border-left:solid 1px var(--gs-border)}.gs-root1 .gs-th-top .gs-th-inner{border-top:solid var(--gs-mx-bt,1px) var(--gs-border)}.gs-root1 .gs-th-left{border-top:solid 1px var(--gs-border)}.gs-root1 .gs-th-left .gs-th-inner{border-left:solid var(--gs-mx-bl,1px) var(--gs-border)}.gs-root1 .gs-search-bar{color:color-mix(in srgb,var(--gs-fg) 40%,transparent)}.gs-root1 .gs-search-bar textarea{color:var(--gs-fg);caret-color:var(--gs-fg)}.gs-editor.gs-editing textarea{caret-color:var(--gs-fg)}.gs-editor.gs-editing .gs-editor-hl{background-color:var(--gs-editor-surface);color:var(--gs-fg)}.gs-editor .gs-editor-options{color:var(--gs-fg);background-color:var(--gs-editor-surface);border:solid 1px var(--gs-border)}:where(.gs-root1[data-mode=dark],.gs-editor[data-mode=dark]){--gs-fg:#e4e6e9;--gs-muted-fg:#8b9096;--gs-border:#2c2f34;--gs-bg:rgba(128, 128, 128, 0.07);--gs-canvas:transparent;--gs-surface:#1c1e21;--gs-editor-surface:#1c1e21;--gs-header-bg:#212327;--gs-header-fg:#a6abb2;--gs-accent:#3b82f6}:where(.gs-root1[data-mode=auto],.gs-editor[data-mode=auto]){--gs-fg:#1f2328;--gs-muted-fg:#6b7280;--gs-border:#e3e6ea;--gs-bg:rgba(128, 128, 128, 0.07);--gs-canvas:transparent;--gs-surface:#ffffff;--gs-editor-surface:#ffffff;--gs-header-bg:#f4f5f7;--gs-header-fg:#59616b;--gs-accent:#2563eb}@media (prefers-color-scheme:dark){:where(.gs-root1[data-mode=auto],.gs-editor[data-mode=auto]){--gs-fg:#e4e6e9;--gs-muted-fg:#8b9096;--gs-border:#2c2f34;--gs-bg:rgba(128, 128, 128, 0.07);--gs-canvas:transparent;--gs-surface:#1c1e21;--gs-editor-surface:#1c1e21;--gs-header-bg:#212327;--gs-header-fg:#a6abb2;--gs-accent:#3b82f6}}:where(.gs-root1[data-mode=inherit-light],.gs-editor[data-mode=inherit-light]){--gs-fg:#1f2328;--gs-muted-fg:#6b7280;--gs-border:#e3e6ea;--gs-bg:rgba(128, 128, 128, 0.07);--gs-surface:#ffffff;--gs-editor-surface:#ffffff;--gs-header-bg:#f4f5f7;--gs-header-fg:#59616b;--gs-accent:#2563eb;--gs-bg:transparent;--gs-canvas:transparent;--gs-surface:transparent;--gs-header-bg:transparent}:where(.gs-root1[data-mode=inherit-dark],.gs-editor[data-mode=inherit-dark]){--gs-fg:#e4e6e9;--gs-muted-fg:#8b9096;--gs-border:#2c2f34;--gs-bg:rgba(128, 128, 128, 0.07);--gs-surface:#1c1e21;--gs-editor-surface:#1c1e21;--gs-header-bg:#212327;--gs-header-fg:#a6abb2;--gs-accent:#3b82f6;--gs-bg:transparent;--gs-canvas:transparent;--gs-surface:transparent;--gs-header-bg:transparent}.gs-root1[data-mode=inherit-dark] .gs-adjuster,.gs-root1[data-mode=inherit-dark] .gs-tabular-inner,.gs-root1[data-mode=inherit-light] .gs-adjuster,.gs-root1[data-mode=inherit-light] .gs-tabular-inner{background-color:transparent}.gs-root1[data-mode=inherit-light] .gs-th{background-color:rgba(128,128,128,.1);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}.gs-root1[data-mode=inherit-dark] .gs-th{background-color:rgba(128,128,128,.1);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}.gs-root1[data-gridlines=horizontal] .gs-cell{border-left-color:transparent;border-right-color:transparent}.gs-root1[data-gridlines=none] .gs-cell{border-color:transparent}.gs-root1[data-density=comfortable] .gs-cell-rendered{padding:0 10px}.gs-cell{transition:border-color .2s ease;padding:0;margin:0;box-sizing:border-box;position:relative;font-size:13px;letter-spacing:1px;line-height:24px;cursor:cell;user-select:none;-webkit-user-select:none;-moz-user-select:none}.gs-cell.gs-copying textarea:focus{outline:solid 1px var(--gs-accent,#2563eb)}.gs-cell.gs-selecting{z-index:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 7%,transparent)}.gs-cell.gs-selecting .gs-cell-label{display:block}.gs-cell.gs-choosing{margin-top:-1px;margin-left:-1px;z-index:1}.gs-cell.gs-choosing.gs-editing{color:transparent}.gs-cell.gs-choosing .gs-cell-label{display:block}.gs-cell.gs-pending .gs-cell-rendered{position:relative;overflow:hidden}.gs-cell.gs-pending .gs-cell-rendered::after{content:'';position:absolute;bottom:0;left:0;height:4px;width:40%;border-radius:1px;background:color-mix(in srgb,var(--gs-accent,#2563eb) 65%,transparent);animation:gs-pending-slide 1.4s ease-in-out infinite}.gs-cell .gs-formula-error-triangle{position:absolute;top:0;right:0;border-top:4px solid rgba(200,0,0,.9);border-right:4px solid rgba(200,0,0,.9);border-bottom:4px solid transparent;border-left:4px solid transparent;z-index:2;cursor:help}.gs-cell .gs-cell-label{font-size:10px;font-weight:500;font-style:normal;font-family:inherit;letter-spacing:.2px;line-height:1.4;position:absolute;top:0;right:0;background-color:var(--gs-accent,#2563eb);color:#fff;padding:1px 5px;border-bottom-left-radius:4px;display:none;opacity:.92}.gs-cell .gs-cell-inner-wrap{width:100%;height:100%;position:absolute;top:0;left:0}.gs-cell .gs-cell-inner{width:100%;height:100%;overflow:hidden;display:flex;box-sizing:border-box;border:none!important}.gs-cell .gs-cell-rendered{overflow:hidden;white-space:pre-wrap;cursor:cell;word-wrap:break-word;word-break:break-all;padding:0 6px;width:100%;height:100%}.gs-cell .gs-cell-rendered>*{position:relative}.gs-cell .gs-cell-rendered>.backface{z-index:0}.gs-cell .gs-autofill-drag{background-color:var(--gs-accent,#2563eb);position:absolute;width:7px;height:7px;bottom:0;right:0;cursor:crosshair;z-index:1}.gs-cell.gs-merged-host{z-index:1}.gs-cell.gs-merged-host.gs-selecting{background-color:transparent}.gs-cell.gs-merged-host.gs-selecting .gs-cell-inner-wrap{background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 7%,transparent)}.gs-cell.gs-merged-covered{z-index:0}.gs-th[data-x="1"] .gs-th-inner-wrap{border-left:none}.gs-th[data-y="1"] .gs-th-inner-wrap{border-top:none}.gs-formula-error-tooltip{position:fixed;background-color:rgba(35,8,8,.94);color:#fff;padding:6px 10px;border-radius:4px;border-left:3px solid rgba(220,50,50,.8);font-size:12px;line-height:1.5;max-width:260px;white-space:pre-wrap;word-break:break-word;box-shadow:0 3px 10px rgba(0,0,0,.4);z-index:100;pointer-events:none;letter-spacing:.3px}.gs-menu-modal{width:100%;height:100vh;z-index:12}.gs-label-input-label{font-size:13px;letter-spacing:1px}.gs-menu-divider{background-color:#aaa;padding:0;margin:5px 0;height:1px;list-style-type:none}.gs-menu-btn{position:absolute;background-color:rgba(128,128,128,.3);border:1px solid #ccc;border-radius:50%;cursor:pointer;font-size:12px;font-weight:700;line-height:1;color:#888;width:18px;height:18px;padding:0;display:flex;align-items:center;justify-content:center;opacity:0;transition:opacity .15s ease;z-index:2}.gs-context-menu{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;opacity:.9;transition:opacity .15s ease}.gs-context-menu:hover{opacity:1}.gs-context-menu .gs-menu-items{color:#555;margin:0;padding:0;min-width:250px}.gs-menu-item{padding:5px 10px;list-style-type:none;display:flex}.gs-menu-item.gs-enabled{cursor:pointer}.gs-menu-item.gs-enabled:hover{background-color:#eee}.gs-menu-item.gs-disabled{opacity:.5;cursor:not-allowed}.gs-menu-item .gs-menu-name{font-size:13px;letter-spacing:1px;flex:1}.gs-submenu-parent{position:relative;align-items:center}.gs-submenu-parent .gs-submenu-arrow{margin-left:8px;font-size:11px;opacity:.6}.gs-submenu-flyout{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;opacity:.9;transition:opacity .15s ease;min-width:200px;margin:0;color:#555;opacity:1;list-style-type:none}.gs-submenu-flyout:hover{opacity:1}.gs-menu-shortcut{font-size:10px;line-height:20px;color:#999}.gs-menu-shortcut:before{content:"( "}.gs-menu-shortcut:after{content:" )"}.gs-menu-shortcut .gs-menu-underline{text-decoration:underline}.gs-column-menu{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;opacity:.9;transition:opacity .15s ease}.gs-column-menu:hover{opacity:1}.gs-column-menu ul{color:#555;margin:0;padding:0;min-width:200px}.gs-column-menu .gs-column-menu-sort{align-items:center}.gs-column-menu .gs-column-menu-sort .gs-sort-buttons{display:flex;gap:4px;margin-left:auto}.gs-column-menu .gs-column-menu-sort .gs-sort-btn{font-size:12px;padding:4px 8px;border:1px solid transparent;border-radius:3px;background-color:rgba(180,180,180,.1);cursor:pointer;color:#555;font-weight:700;letter-spacing:.5px}.gs-column-menu .gs-column-menu-sort .gs-sort-btn:hover:not(:disabled){border-color:#555}.gs-column-menu .gs-column-menu-sort .gs-sort-btn:disabled{opacity:.5;cursor:not-allowed}.gs-column-menu .gs-column-menu-label{padding:5px 10px}.gs-column-menu .gs-label-input-row{display:flex;gap:4px;align-items:center}.gs-column-menu .gs-label-input{flex:1;font-size:13px;padding:4px 6px;border:none;border-bottom:1px solid #ccc;border-radius:0;outline:0;min-width:0;width:100px;background-color:transparent;box-shadow:none}.gs-column-menu .gs-label-input:focus{border-bottom-color:var(--gs-accent,#2563eb);outline:0;box-shadow:none}.gs-column-menu .gs-label-apply-btn{font-size:12px;padding:4px 8px;border:1px solid transparent;border-radius:3px;background-color:rgba(180,180,180,.1);cursor:pointer;color:#555;font-weight:700;letter-spacing:.5px}.gs-column-menu .gs-label-apply-btn:hover:not(:disabled){border-color:#555}.gs-column-menu .gs-label-apply-btn:disabled{opacity:.5;cursor:not-allowed}.gs-column-menu .gs-column-menu-filter{padding:5px 10px;list-style-type:none;font-size:13px}.gs-column-menu .gs-filter-header{display:flex;align-items:center;gap:8px}.gs-column-menu .gs-filter-header .gs-filter-add-btn{font-size:12px;padding:3px 9px;border:1px solid transparent;border-radius:3px;background-color:rgba(180,180,180,.1);cursor:pointer;color:#555;letter-spacing:1px}.gs-column-menu .gs-filter-header .gs-filter-add-btn:hover{border-color:#555}.gs-column-menu .gs-filter-mode-toggle{display:flex;gap:6px;margin-left:auto}.gs-column-menu .gs-filter-mode-toggle label{display:flex;align-items:center;gap:3px;font-size:11px;font-weight:700;letter-spacing:.5px;color:#888;cursor:pointer;user-select:none}.gs-column-menu .gs-filter-mode-toggle label input[type=radio]{margin:0;cursor:pointer}.gs-column-menu .gs-filter-mode-toggle label.gs-active{color:var(--gs-accent,#2563eb)}.gs-column-menu .gs-filter-mode-toggle.gs-disabled{opacity:.4;pointer-events:none}.gs-column-menu .gs-filter-conditions{display:flex;flex-direction:column;gap:5px;margin-top:6px;max-height:200px;overflow-y:auto}.gs-column-menu .gs-filter-condition-row{display:flex;gap:4px;align-items:normal}.gs-column-menu .gs-filter-method-select{font-size:12px;padding:4px 4px;border:none;border-bottom:1px solid #ccc;border-radius:0;outline:0;background-color:#fff;box-shadow:none;min-width:40px;max-width:80px;cursor:pointer}.gs-column-menu .gs-filter-method-select:focus{border-bottom-color:var(--gs-accent,#2563eb);outline:0;box-shadow:none}.gs-column-menu .gs-filter-value-input{flex:1;font-size:13px;padding:4px 6px;border:none;border-bottom:1px solid #ccc;border-radius:0;outline:0;min-width:0;width:80px;background-color:transparent;box-shadow:none}.gs-column-menu .gs-filter-value-input:focus{border-bottom-color:var(--gs-accent,#2563eb);outline:0;box-shadow:none}.gs-column-menu .gs-filter-remove-btn{font-size:12px;padding:0;border:none;border-radius:3px;background-color:transparent;cursor:pointer;color:#999;line-height:1;flex-shrink:0}.gs-column-menu .gs-filter-remove-btn:hover{color:#c33}.gs-column-menu .gs-filter-actions{display:flex;gap:4px;margin-top:10px;align-items:center}.gs-column-menu .gs-filter-actions .gs-filter-reset-all-btn{font-size:12px;padding:3px 9px;border:1px solid transparent;border-radius:3px;background-color:transparent;cursor:pointer;color:#c33;font-weight:700;letter-spacing:1px}.gs-column-menu .gs-filter-actions .gs-filter-reset-all-btn:hover{border-color:#c33}.gs-column-menu .gs-filter-actions .gs-filter-actions-right{display:flex;gap:4px;margin-left:auto}.gs-column-menu .gs-filter-actions .gs-filter-reset-btn{font-size:12px;padding:3px 9px;border:1px solid transparent;border-radius:3px;background-color:transparent;cursor:pointer;color:#e08000;font-weight:700;letter-spacing:1px}.gs-column-menu .gs-filter-actions .gs-filter-reset-btn:hover{border-color:#e08000}.gs-column-menu .gs-filter-actions .gs-filter-apply-btn{font-size:12px;padding:3px 6px;border:1px solid transparent;border-radius:3px;background-color:transparent;color:var(--gs-accent,#2563eb);cursor:pointer;font-weight:700;letter-spacing:1px}.gs-column-menu .gs-filter-actions .gs-filter-apply-btn:hover{border-color:var(--gs-accent,#2563eb)}.gs-column-menu-waiting{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:20px 30px;gap:12px;min-width:180px}.gs-column-menu-waiting .gs-waiting-message{font-size:13px;font-weight:700;color:#555;letter-spacing:.5px}.gs-column-menu-waiting .gs-waiting-spinner{width:24px;height:24px;border:3px solid #e0e0e0;border-top-color:var(--gs-accent,#2563eb);border-radius:50%;animation:spin .8s linear infinite}.gs-column-menu-waiting .gs-waiting-cancel-btn{font-size:12px;padding:4px 18px;border:1px solid #c33;border-radius:3px;background-color:transparent;color:#c33;cursor:pointer;font-weight:700;letter-spacing:1px}.gs-column-menu-waiting .gs-waiting-cancel-btn:hover{background-color:#c33;color:#fff}.gs-column-menu-btn{right:4px;top:50%;transform:translateY(-50%)}.gs-column-menu-btn.gs-filtered{opacity:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);border-color:var(--gs-accent,#2563eb);color:var(--gs-accent,#2563eb)}.gs-column-menu-btn.gs-active{opacity:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 18%,transparent);border-color:var(--gs-accent,#2563eb);color:var(--gs-accent,#2563eb)}.gs-th-top:hover .gs-column-menu-btn{opacity:1}.gs-row-menu{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;opacity:.9;transition:opacity .15s ease}.gs-row-menu:hover{opacity:1}.gs-row-menu ul{color:#555;margin:0;padding:0;min-width:200px}.gs-row-fixed-toggle{display:flex;align-items:center;gap:6px}.gs-row-fixed-check{font-size:12px;width:14px;text-align:center;color:transparent}.gs-row-fixed-check.gs-row-fixed-active{color:var(--gs-accent,#2563eb)}.gs-row-menu-btn{top:50%;transform:translateY(-50%);right:2px}.gs-row-menu-btn.gs-active{opacity:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 18%,transparent);border-color:var(--gs-accent,#2563eb);color:var(--gs-accent,#2563eb)}.gs-th-left:hover .gs-row-menu-btn{opacity:1}.gs-corner-menu-btn{bottom:2px;right:2px}.gs-corner-menu-btn:hover{opacity:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 18%,transparent);border-color:var(--gs-accent,#2563eb);color:var(--gs-accent,#2563eb)}.gs-th-left.gs-th-top:hover .gs-corner-menu-btn{opacity:1}.gs-editor-hl{padding:0 2px!important;position:absolute;font-family:monospace,Arial;font-size:12px;line-height:24px;letter-spacing:1px}.gs-formula-bar-editor-inner{position:relative;flex:1;min-width:0;display:flex;align-items:center}.gs-editor{opacity:0;z-index:-1}.gs-editor .gs-editor-inner{position:relative}.gs-editor .gs-editor-hl{box-sizing:content-box;border:solid 2px var(--gs-accent,#2563eb);margin:-2px -1px}.gs-editor textarea{width:100%;padding:0 2px!important;position:absolute;font-size:12px;font-family:monospace,Arial;line-height:24px;letter-spacing:1px;top:0;left:0;border:none;outline:0;background-color:transparent;color:transparent;resize:none;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;overflow:hidden;cursor:default;white-space:pre;height:auto}.gs-editor.gs-editing{z-index:11;opacity:1}.gs-editor.gs-editing .gs-cell-label{pointer-events:none;font-family:inherit;font-weight:500;position:absolute;top:0;right:0;margin-top:-17px;margin-right:-2px;padding:1px 5px;border-top-left-radius:4px;border-top-right-radius:4px;font-size:10px;background-color:var(--gs-accent,#2563eb);color:#fff;z-index:1}.gs-formula-bar{width:100%;position:relative;display:flex;align-items:stretch;box-sizing:border-box;border-style:solid;border-color:var(--gs-border,#e3e6ea);border-width:var(--gs-fb-bt,1px) var(--gs-fb-br,1px) var(--gs-fb-bb,1px) var(--gs-fb-bl,1px);padding:3px 6px;gap:6px}.gs-formula-bar .gs-selecting-address{display:flex;align-items:center;justify-content:center;min-width:38px;padding:0 4px;color:var(--gs-muted-fg,#6b7280);font-size:12px;font-variant-numeric:tabular-nums;text-align:center}.gs-formula-bar[data-spill=true]{background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 6%,var(--gs-header-bg,#f4f5f7))}.gs-formula-bar[data-spill=true] .gs-selecting-address{color:var(--gs-accent,#2563eb);font-style:italic}.gs-formula-bar[data-spill=true] .gs-selecting-address::after{content:"\\2196";margin-left:2px;font-style:normal;font-size:9px}.gs-formula-bar .gs-fx{display:flex;align-items:center;justify-content:center;align-self:center;width:26px;height:18px;flex-shrink:0;color:var(--gs-muted-fg,#6b7280);font-style:italic;font-family:inherit;font-weight:400;text-align:center;font-size:13px;letter-spacing:.3px;border-radius:4px;background-color:color-mix(in srgb,var(--gs-fg,#1f2328) 6%,transparent)}.gs-formula-bar .gs-editor-hl{z-index:0;overflow-y:auto;box-sizing:border-box;white-space:pre-wrap;word-break:break-all;text-align:left;line-height:24px}.gs-formula-bar textarea{position:relative;z-index:1;width:100%;vertical-align:bottom;color:transparent;border:none;background-color:transparent;padding:0 2px;box-sizing:border-box;text-align:left;outline:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;font-size:12px;font-family:monospace,Arial;height:24px;line-height:24px;min-height:24px;letter-spacing:1px;resize:vertical;caret-color:var(--gs-fg,#1f2328);white-space:pre-wrap;word-break:break-all}.gs-token-type-INVALID_REF{color:red}.gs-token-type-VALUE.gs-token-entity-type-boolean,.gs-token-type-VALUE.gs-token-entity-type-number{color:#39f}.gs-token-type-VALUE.gs-token-entity-type-string{color:#090}.gs-editor-options{position:fixed;z-index:1000;padding:4px;background:var(--gs-bg,#fff);box-shadow:0 4px 12px rgba(0,0,0,.15);border:1px solid rgba(0,0,0,.1);border-radius:6px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;overflow:visible}.gs-editor-option{position:relative;cursor:pointer;list-style:none;padding:6px 12px;font-size:13px;border-radius:4px;color:#333;margin-bottom:2px}.gs-editor-option-content{display:flex;justify-content:space-between;width:100%;align-items:center}.gs-editor-option-tab{font-size:10px;color:#aaa;margin-left:8px;padding:2px 4px;border:1px solid #ddd;border-radius:3px;background:#f9f9f9}.gs-editor-option:last-child{margin-bottom:0}.gs-editor-option:hover{background-color:#f5f5f5}.gs-editor-option-selected{background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);color:var(--gs-accent,#2563eb);font-weight:500}.gs-editor-option-selected:hover{background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 18%,transparent)}.gs-fn-guide1{position:absolute;top:-4px;left:calc(100% + 8px);background:#fff;border:1px solid rgba(0,0,0,.1);box-shadow:0 4px 16px rgba(0,0,0,.12);border-radius:6px;padding:16px;width:280px;z-index:1000;cursor:default;white-space:normal;color:#333}.gs-fn-guide1-tooltip{margin-bottom:8px;line-height:1.4;font-size:13px}.gs-fn-guide1-example{font-family:monospace;font-weight:600;font-size:13px;margin-bottom:8px;color:#1a1a1a;background:#f5f5f5;padding:6px 8px;border-radius:4px;border:1px solid #eee;display:flex;align-items:center;gap:6px;flex-wrap:wrap}.gs-fn-guide1-desc{font-size:13px;color:#555;margin-bottom:12px;line-height:1.4}.gs-fn-guide1-desc p{margin:0 0 6px 0}.gs-fn-guide1-desc p:last-child{margin-bottom:0}.gs-fn-guide1-args{border-top:1px solid #eee;padding-top:10px}.gs-fn-guide1-arg{margin-bottom:6px;line-height:1.4;font-size:12px}.gs-fn-guide1-arg-name{font-weight:600;color:var(--gs-accent,#2563eb)}.gs-fn-guide1-arg-opt{color:#888;font-size:11px}.gs-fn-guide1-arg-iter{font-weight:600;color:var(--gs-accent,#2563eb)}.gs-fn-guide1-arg-type{color:var(--gs-accent,#2563eb);padding:0 4px;background:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);border-radius:3px;font-size:11px;margin:0 4px}.gs-fn-guide1-arg-desc{color:#666}.gs-fn-guide-category{position:absolute;top:-11px;right:8px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;font-size:11px;font-weight:600;letter-spacing:.5px;text-transform:uppercase;padding:2px 7px;border-radius:4px;background:#e8eaf6;color:#3949ab;border:1px solid #c5cae9;white-space:nowrap}.gs-fn-guide-category.gs-fn-guide-category-math{background:#e3f2fd;color:#1565c0;border-color:#bbdefb}.gs-fn-guide-category.gs-fn-guide-category-statistics{background:#e8f5e9;color:#2e7d32;border-color:#c8e6c9}.gs-fn-guide-category.gs-fn-guide-category-text{background:#fff8e1;color:#f57f17;border-color:#ffecb3}.gs-fn-guide-category.gs-fn-guide-category-time{background:#fce4ec;color:#880e4f;border-color:#f8bbd0}.gs-fn-guide-category.gs-fn-guide-category-lookup{background:#f3e5f5;color:#6a1b9a;border-color:#e1bee7}.gs-fn-guide-category.gs-fn-guide-category-logical{background:#e0f2f1;color:#00695c;border-color:#b2dfdb}.gs-fn-guide-category.gs-fn-guide-category-information{background:#e0f7fa;color:#006064;border-color:#b2ebf2}.gs-fn-guide-category.gs-fn-guide-category-finance{background:#fff3e0;color:#e65100;border-color:#ffe0b2}.gs-fn-guide-category.gs-fn-guide-category-engineering{background:#efebe9;color:#4e342e;border-color:#d7ccc8}.gs-fn-guide-category.gs-fn-guide-category-ai{background:#e8eaf6;color:#3949ab;border-color:#c5cae9}.gs-fn-guide-category.gs-fn-guide-category-other{background:#f5f5f5;color:#616161;border-color:#e0e0e0}.gs-editor-portal{display:contents}.gs-editor-portal[data-mode=dark] .gs-editor-options,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-options,.gs-editor[data-mode=dark] .gs-editor-options,.gs-editor[data-mode=inherit-dark] .gs-editor-options{background:#252526;border-color:#454545;box-shadow:0 4px 12px rgba(0,0,0,.5)}.gs-editor-portal[data-mode=dark] .gs-editor-option,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option,.gs-editor[data-mode=dark] .gs-editor-option,.gs-editor[data-mode=inherit-dark] .gs-editor-option{color:#ccc}.gs-editor-portal[data-mode=dark] .gs-editor-option:hover,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option:hover,.gs-editor[data-mode=dark] .gs-editor-option:hover,.gs-editor[data-mode=inherit-dark] .gs-editor-option:hover{background-color:#333}.gs-editor-portal[data-mode=dark] .gs-editor-option-selected,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option-selected,.gs-editor[data-mode=dark] .gs-editor-option-selected,.gs-editor[data-mode=inherit-dark] .gs-editor-option-selected{background-color:#094771;color:#fff}.gs-editor-portal[data-mode=dark] .gs-editor-option-selected:hover,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option-selected:hover,.gs-editor[data-mode=dark] .gs-editor-option-selected:hover,.gs-editor[data-mode=inherit-dark] .gs-editor-option-selected:hover{background-color:#0d5a8f}.gs-editor-portal[data-mode=dark] .gs-editor-option-tab,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option-tab,.gs-editor[data-mode=dark] .gs-editor-option-tab,.gs-editor[data-mode=inherit-dark] .gs-editor-option-tab{color:#777;background:#333;border-color:#444}.gs-editor-portal[data-mode=dark] .gs-fn-guide1,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1,.gs-editor[data-mode=dark] .gs-fn-guide1,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1{background:#252526;border-color:#454545;color:#ccc}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-example,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-example,.gs-editor[data-mode=dark] .gs-fn-guide1-example,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-example{background:#1e1e1e;border-color:#333;color:#d4d4d4}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-desc,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-desc,.gs-editor[data-mode=dark] .gs-fn-guide1-desc,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-desc{color:#aaa}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-args,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-args,.gs-editor[data-mode=dark] .gs-fn-guide1-args,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-args{border-color:#333}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-iter,.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-name,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-iter,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-name,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-iter,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-name,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-iter,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-name{color:#4fc1ff}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-opt,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-opt,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-opt,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-opt{color:#777}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-type,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-type,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-type,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-type{background:#094771;color:#4fc1ff}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-desc,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-desc,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-desc,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-desc{color:#999}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category,.gs-editor[data-mode=dark] .gs-fn-guide-category,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category{background:#2a2d3e;color:#7986cb;border-color:#3d4166}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-math,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-math,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-math,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-math{background:#0d2137;color:#64b5f6;border-color:#1a3a5c}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-statistics,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-statistics,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-statistics,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-statistics{background:#0d2218;color:#66bb6a;border-color:#1a3d2a}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-text,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-text,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-text,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-text{background:#2e2200;color:#ffd54f;border-color:#4d3900}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-time,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-time,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-time,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-time{background:#2d0d1e;color:#f48fb1;border-color:#4d1a33}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-lookup,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-lookup,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-lookup,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-lookup{background:#260d33;color:#ce93d8;border-color:#3d1a54}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-logical,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-logical,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-logical,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-logical{background:#0d2421;color:#4db6ac;border-color:#1a3d39}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-information,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-information,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-information,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-information{background:#0d2426;color:#4dd0e1;border-color:#1a3d40}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-finance,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-finance,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-finance,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-finance{background:#2e1500;color:#ffb74d;border-color:#4d2800}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-engineering,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-engineering,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-engineering,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-engineering{background:#1e1714;color:#bcaaa4;border-color:#332c28}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-ai,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-ai,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-ai,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-ai{background:#10142e;color:#7986cb;border-color:#232a52}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-other,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-other,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-other,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-other{background:#1e1e1e;color:#9e9e9e;border-color:#333}.gs-editor-portal[data-mode=dark] .gs-fn-guide2,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2,.gs-editor[data-mode=dark] .gs-fn-guide2,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2{background:#252526;border-color:#454545;box-shadow:0 4px 12px rgba(0,0,0,.5);color:#ccc}.gs-editor-portal[data-mode=dark] .gs-fn-guide2-name,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2-name,.gs-editor[data-mode=dark] .gs-fn-guide2-name,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2-name{color:#dfdbdb;background:#333;border-color:#444}.gs-editor-portal[data-mode=dark] .gs-fn-guide2 .gs-active-arg,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2 .gs-active-arg,.gs-editor[data-mode=dark] .gs-fn-guide2 .gs-active-arg,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2 .gs-active-arg{color:#fff;background-color:#094771}.gs-editor-portal[data-mode=dark] .gs-fn-guide2-arg-type,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2-arg-type,.gs-editor[data-mode=dark] .gs-fn-guide2-arg-type,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2-arg-type{background:#094771;color:#4fc1ff}.gs-editor-portal[data-mode=dark] .gs-fn-guide2-desc,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2-desc,.gs-editor[data-mode=dark] .gs-fn-guide2-desc,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2-desc{color:#aaa;border-top-color:#333}.gs-fn-guide2{position:fixed;left:0;background:#fff;border:1px solid rgba(0,0,0,.1);box-shadow:0 4px 16px rgba(0,0,0,.12);border-radius:6px;padding:12px 16px;width:280px;z-index:1000;cursor:default;white-space:normal;color:#333;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;transition:opacity .1s ease-in-out}.gs-fn-guide2.gs-fn-guide2-hidden{opacity:0!important;pointer-events:none!important}.gs-fn-guide2-name{font-family:monospace;font-weight:700;font-size:13px;color:#1a1a1a;background:#f5f5f5;padding:6px 8px;border-radius:4px;border:1px solid #eee;display:flex;align-items:center;gap:6px;flex-wrap:wrap;width:100%;box-sizing:border-box;margin-bottom:8px}.gs-fn-guide2-args-inline{font-size:13px;font-family:monospace;line-height:1.5;margin-bottom:8px;color:#666}.gs-fn-guide2-args-inline span{transition:all .2s ease-in-out}.gs-fn-guide2 .gs-active-arg{font-weight:700;color:var(--gs-accent,#2563eb);background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);padding:2px 4px;margin:0 -4px;border-radius:4px}.gs-fn-guide2-arg-type{color:var(--gs-accent,#2563eb);padding:0 4px;background:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);border-radius:3px;font-size:11px;margin:0 4px}.gs-fn-guide2-desc{font-size:12px;color:#555;line-height:1.4;border-top:1px solid #eee;padding-top:8px;margin-top:4px}.gs-fn-guide2-desc p{margin:0}.gs-fn-guide2-desc-more{font-style:italic;color:#888;margin-top:4px!important;font-size:11px}.gs-adjuster{padding:0}.gs-table{margin:0}.gs-tabular{overflow:auto;overflow-anchor:none;display:flex;box-sizing:border-box;position:relative}.gs-root1[data-matrix-align=both] .gs-tabular,.gs-root1[data-matrix-align=horizontal] .gs-tabular{justify-content:safe center}.gs-root1[data-matrix-align=both] .gs-tabular,.gs-root1[data-matrix-align=vertical] .gs-tabular{align-items:safe center}.gs-tabular-inner{flex:0 0 auto;position:relative;overflow:hidden;overflow:clip;box-sizing:border-box;border-right:solid var(--gs-mx-br,1px) var(--gs-border,#e3e6ea);border-bottom:solid var(--gs-mx-bb,1px) var(--gs-border,#e3e6ea)}.gs-tabular-inner>table{table-layout:fixed;border-collapse:collapse;border-spacing:0}.gs-ghost-cell{padding:0;box-sizing:border-box;border:dashed 1px var(--gs-border,#e3e6ea);background-color:var(--gs-surface,#fff);opacity:.5;cursor:crosshair}.gs-ghost-th{opacity:.5}.gs-ghost-th-top{top:0}.gs-ghost-th-left{left:0}.gs-main[data-overflow-x=true] .gs-tabular-inner{border-right-width:0}.gs-main[data-overflow-y=true] .gs-tabular-inner{border-bottom-width:0}.gs-main::after{content:'';position:absolute;inset:0;pointer-events:none;z-index:3;border:0 solid var(--gs-border,#e3e6ea)}.gs-main[data-overflow-x=true]::after{border-right-width:var(--gs-mx-br,1px)}.gs-main[data-overflow-y=true]::after{border-bottom-width:var(--gs-mx-bb,1px)}.gs-th{z-index:2;padding:0;position:sticky;font-size:13px;font-weight:400;box-sizing:border-box;vertical-align:top}.gs-th .gs-resizer{position:absolute;border-color:transparent;box-sizing:border-box;z-index:2}.gs-th .gs-resizer:hover{background-color:var(--gs-accent,#2563eb)}.gs-th .gs-resizer.gs-protected{display:none}.gs-th-inner{height:100%;box-sizing:border-box;vertical-align:middle;overflow:hidden;display:flex;align-items:center;justify-content:center}.gs-th-inner-wrap{height:100%;box-sizing:border-box;background-color:transparent}.gs-th-top{top:0;overflow:hidden}.gs-th-top .gs-resizer{top:0;right:0;width:3px;cursor:e-resize}.gs-th-top .gs-resizer.gs-dragging{border-right-style:dotted;height:1000000px!important;cursor:e-resize}.gs-th-left{left:0;overflow:hidden;min-width:30px;border-top:solid 1px var(--gs-border,#e3e6ea)}.gs-th-left .gs-resizer{left:0;bottom:0;height:3px;cursor:n-resize}.gs-th-left .gs-resizer.gs-dragging{border-bottom-style:dotted;width:1000000px!important;cursor:n-resize}.gs-th-top.gs-th-left{top:0;left:0;z-index:3;border:none!important}.gs-th-left.gs-filter-fixed .gs-th-inner::before{content:'‹\\00a0'}.gs-th-left.gs-sort-fixed .gs-th-inner::after{content:'\\00a0›'}.gs-col-addr{position:absolute;top:2px;right:4px;font-size:9px;opacity:.5;line-height:1;letter-spacing:.3px;pointer-events:none}.gs-search-bar{width:100%;display:flex;align-items:center;padding:3px 0;border-top:solid 1px rgba(128,128,128,.3);border-left:solid 1px rgba(128,128,128,.3);border-right:solid 1px rgba(128,128,128,.3);border-bottom:solid 1px rgba(128,128,128,.3);box-sizing:border-box;background-color:rgba(200,50,0,.2)}.gs-search-bar.gs-search-found{background-color:rgba(0,200,100,.2)}.gs-search-bar .gs-search-bar-inner{border-left:solid 1px rgba(128,128,128,.5)}.gs-search-bar .gs-search-bar-icon{border-left:solid 1px rgba(128,128,128,.3);display:flex;align-items:center;justify-content:center;width:30px;flex-shrink:0}.gs-search-bar .gs-search-input-wrapper{flex-grow:1;position:relative;display:flex;align-items:center;height:100%}.gs-search-bar .gs-search-input-ghost{position:absolute;left:2px;right:2px;top:0;bottom:0;pointer-events:none;font-size:12px;font-family:monospace,Arial;line-height:24px;letter-spacing:1px;white-space:pre-wrap;word-break:break-all;color:transparent;overflow:hidden}.gs-search-bar .gs-search-input-ghost .gs-search-ghost-hint{color:#aaa}.gs-search-bar textarea{background-color:transparent;border:none;padding:0 2px;box-sizing:border-box;outline:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;font-size:12px;font-family:monospace,Arial;height:24px;line-height:24px;min-height:24px;letter-spacing:1px;caret-color:rgba(128,128,128);white-space:pre-wrap;word-break:break-all;flex-grow:1;width:100%;resize:none}.gs-search-progress{color:#999;font-size:13px;width:60px;flex-shrink:0;white-space:nowrap;text-align:center}.gs-search-close{cursor:pointer;display:flex;align-items:center;justify-content:center;width:24px;flex-shrink:0}.gs-search-buttons{display:flex;align-items:center;white-space:nowrap;flex-shrink:0}.gs-search-button{display:inline-flex;cursor:pointer;margin:0 2px}.gs-search-button span{display:inline-block;font-size:11px;padding:3px 5px;background-color:rgba(128,128,128,.1);border:1px solid rgba(128,128,128,.3);border-radius:3px;transition:all .15s ease;line-height:1}.gs-search-button span:hover{background-color:rgba(128,128,128,.2)}.gs-search-button span.gs-search-button-on{color:var(--gs-accent,#2563eb);background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 22%,transparent);border-color:var(--gs-accent,#2563eb)}.gs-search-range span{white-space:nowrap;font-family:monospace}@keyframes spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}.gs-loading-overlay{position:absolute;top:0;left:0;right:0;bottom:0;background:color-mix(in srgb,var(--gs-surface,#fff) 70%,transparent);display:flex;align-items:center;justify-content:center;z-index:100;pointer-events:all}.gs-loading-spinner{width:32px;height:32px;border:3px solid color-mix(in srgb,var(--gs-fg,#1f2328) 12%,transparent);border-top-color:var(--gs-accent,#2563eb);border-radius:50%;animation:spin .8s linear infinite}.gs-progress-overlay{position:absolute;top:0;left:0;right:0;bottom:0;z-index:100;pointer-events:all;display:flex;align-items:center;justify-content:center}.gs-progress-box{min-width:240px;padding:16px 18px;border-radius:8px;background:var(--gs-editor-surface,#fff);border:1px solid var(--gs-border,#e3e6ea);box-shadow:0 6px 24px rgba(0,0,0,.28);display:flex;flex-direction:column;gap:10px}.gs-progress-head{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--gs-fg,#1f2328)}.gs-progress-head .gs-loading-spinner{width:15px;height:15px;border-width:2px}.gs-progress-track{height:6px;border-radius:3px;overflow:hidden;background:color-mix(in srgb,var(--gs-fg,#1f2328) 12%,transparent)}.gs-progress-fill{height:100%;border-radius:3px;background:var(--gs-accent,#2563eb);transition:width .1s linear}@keyframes gs-pending-slide{0%{left:-40%}100%{left:100%}}@keyframes gs-pending-pulse{0%{left:0;width:0}50%{left:0;width:100%}100%{left:100%;width:0}}@keyframes gs-flash{0%{opacity:0}20%{opacity:1}100%{opacity:0}}.gs-flash-overlay{position:absolute;inset:0;pointer-events:none;z-index:9999;background:color-mix(in srgb,var(--gs-accent,#2563eb) 15%,transparent);opacity:0}.gs-flash-overlay--active{animation:gs-flash .6s ease-out forwards}`; diff --git a/packages/web/src/styles/root.min.css b/packages/web/src/styles/root.min.css index a6ec67e3..6e6e0901 100644 --- a/packages/web/src/styles/root.min.css +++ b/packages/web/src/styles/root.min.css @@ -1 +1 @@ -.gs-root1{display:inline-block;position:relative;border-spacing:0;width:fit-content;max-width:100%;overflow:auto;font-family:"SF Pro Text","SF Pro Icons","Helvetica Neue",Helvetica,Arial,Meiryo,sans-serif;visibility:hidden;opacity:0}.gs-root1.gs-initialized{visibility:visible;opacity:1;transition:opacity .2s ease-in-out}.gs-root1 .gs-main{flex:1;max-width:100%;overflow:hidden;position:relative;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box}.gs-root1 .gs-resizing{width:100%;height:100%;position:absolute;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 8%,transparent);top:0;left:0;z-index:2}.gs-root1 .gs-line-horizontal{width:100%}.gs-root1 .gs-line-vertical{height:100%}.gs-root1 .gs-line{position:relative;top:0;left:0;border:dotted 1px var(--gs-accent,#2563eb);box-sizing:border-box}.gs-root1 .gs-line span{font-size:10px;padding:3px;background-color:var(--gs-accent,#2563eb);color:#fff;margin:0;position:absolute;top:0;left:0}.gs-root1 .gs-scroll-handle{width:100%;height:100%;cursor:cell}.gs-hidden{visibility:hidden;position:absolute;top:0;left:0;width:0;height:0;overflow:hidden;pointer-events:none;z-index:-1}.gs-fixed{position:fixed;top:0;left:0;z-index:1}:where(.gs-root1[data-mode=light],.gs-editor[data-mode=light]){--gs-fg:#1f2328;--gs-muted-fg:#6b7280;--gs-border:#e3e6ea;--gs-bg:rgba(128, 128, 128, 0.07);--gs-canvas:transparent;--gs-surface:#ffffff;--gs-editor-surface:#ffffff;--gs-header-bg:#f4f5f7;--gs-header-fg:#59616b;--gs-accent:#2563eb}.gs-root1{background-color:var(--gs-bg);color:var(--gs-fg)}.gs-root1 .gs-main{background-color:var(--gs-canvas)}.gs-root1 .gs-tabular{background-color:var(--gs-canvas)}.gs-root1 .gs-sheet-body-data{background-color:var(--gs-surface)}.gs-root1 .gs-formula-bar{background-color:var(--gs-header-bg)}.gs-root1 .gs-formula-bar-editor-inner{color:var(--gs-fg)}.gs-root1 .gs-cell{border:solid 1px var(--gs-border)}.gs-root1 .gs-adjuster{background-color:var(--gs-border)}.gs-root1 .gs-tabular-inner{background-color:var(--gs-border)}.gs-root1 .gs-large-editor textarea{color:var(--gs-fg);caret-color:var(--gs-fg)}.gs-root1 .gs-th{background-color:var(--gs-header-bg);color:var(--gs-header-fg)}.gs-root1 .gs-th-top{border-left:solid 1px var(--gs-border)}.gs-root1 .gs-th-top .gs-th-inner{border-top:solid var(--gs-mx-bt,1px) var(--gs-border)}.gs-root1 .gs-th-left{border-top:solid 1px var(--gs-border)}.gs-root1 .gs-th-left .gs-th-inner{border-left:solid var(--gs-mx-bl,1px) var(--gs-border)}.gs-root1 .gs-search-bar{color:color-mix(in srgb,var(--gs-fg) 40%,transparent)}.gs-root1 .gs-search-bar textarea{color:var(--gs-fg);caret-color:var(--gs-fg)}.gs-editor.gs-editing textarea{caret-color:var(--gs-fg)}.gs-editor.gs-editing .gs-editor-hl{background-color:var(--gs-editor-surface);color:var(--gs-fg)}.gs-editor .gs-editor-options{color:var(--gs-fg);background-color:var(--gs-editor-surface);border:solid 1px var(--gs-border)}:where(.gs-root1[data-mode=dark],.gs-editor[data-mode=dark]){--gs-fg:#e4e6e9;--gs-muted-fg:#8b9096;--gs-border:#2c2f34;--gs-bg:rgba(128, 128, 128, 0.07);--gs-canvas:transparent;--gs-surface:#1c1e21;--gs-editor-surface:#1c1e21;--gs-header-bg:#212327;--gs-header-fg:#a6abb2;--gs-accent:#3b82f6}:where(.gs-root1[data-mode=auto],.gs-editor[data-mode=auto]){--gs-fg:#1f2328;--gs-muted-fg:#6b7280;--gs-border:#e3e6ea;--gs-bg:rgba(128, 128, 128, 0.07);--gs-canvas:transparent;--gs-surface:#ffffff;--gs-editor-surface:#ffffff;--gs-header-bg:#f4f5f7;--gs-header-fg:#59616b;--gs-accent:#2563eb}@media (prefers-color-scheme:dark){:where(.gs-root1[data-mode=auto],.gs-editor[data-mode=auto]){--gs-fg:#e4e6e9;--gs-muted-fg:#8b9096;--gs-border:#2c2f34;--gs-bg:rgba(128, 128, 128, 0.07);--gs-canvas:transparent;--gs-surface:#1c1e21;--gs-editor-surface:#1c1e21;--gs-header-bg:#212327;--gs-header-fg:#a6abb2;--gs-accent:#3b82f6}}:where(.gs-root1[data-mode=inherit-light],.gs-editor[data-mode=inherit-light]){--gs-fg:#1f2328;--gs-muted-fg:#6b7280;--gs-border:#e3e6ea;--gs-bg:rgba(128, 128, 128, 0.07);--gs-surface:#ffffff;--gs-editor-surface:#ffffff;--gs-header-bg:#f4f5f7;--gs-header-fg:#59616b;--gs-accent:#2563eb;--gs-bg:transparent;--gs-canvas:transparent;--gs-surface:transparent;--gs-header-bg:transparent}:where(.gs-root1[data-mode=inherit-dark],.gs-editor[data-mode=inherit-dark]){--gs-fg:#e4e6e9;--gs-muted-fg:#8b9096;--gs-border:#2c2f34;--gs-bg:rgba(128, 128, 128, 0.07);--gs-surface:#1c1e21;--gs-editor-surface:#1c1e21;--gs-header-bg:#212327;--gs-header-fg:#a6abb2;--gs-accent:#3b82f6;--gs-bg:transparent;--gs-canvas:transparent;--gs-surface:transparent;--gs-header-bg:transparent}.gs-root1[data-mode=inherit-dark] .gs-adjuster,.gs-root1[data-mode=inherit-dark] .gs-tabular-inner,.gs-root1[data-mode=inherit-light] .gs-adjuster,.gs-root1[data-mode=inherit-light] .gs-tabular-inner{background-color:transparent}.gs-root1[data-mode=inherit-light] .gs-th{background-color:rgba(128,128,128,.1);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}.gs-root1[data-mode=inherit-dark] .gs-th{background-color:rgba(128,128,128,.1);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}.gs-root1[data-gridlines=horizontal] .gs-cell{border-left-color:transparent;border-right-color:transparent}.gs-root1[data-gridlines=none] .gs-cell{border-color:transparent}.gs-root1[data-density=comfortable] .gs-cell-rendered{padding:0 10px}.gs-cell{transition:border-color .2s ease;padding:0;margin:0;box-sizing:border-box;position:relative;font-size:13px;letter-spacing:1px;line-height:24px;cursor:cell;user-select:none;-webkit-user-select:none;-moz-user-select:none}.gs-cell.gs-copying textarea:focus{outline:solid 1px var(--gs-accent,#2563eb)}.gs-cell.gs-selecting{z-index:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 7%,transparent)}.gs-cell.gs-selecting .gs-cell-label{display:block}.gs-cell.gs-choosing{margin-top:-1px;margin-left:-1px;z-index:1}.gs-cell.gs-choosing.gs-editing{color:transparent}.gs-cell.gs-choosing .gs-cell-label{display:block}.gs-cell.gs-pending .gs-cell-rendered{position:relative;overflow:hidden}.gs-cell.gs-pending .gs-cell-rendered::after{content:'';position:absolute;bottom:0;left:0;height:4px;width:40%;border-radius:1px;background:color-mix(in srgb,var(--gs-accent,#2563eb) 65%,transparent);animation:gs-pending-slide 1.4s ease-in-out infinite}.gs-cell .gs-formula-error-triangle{position:absolute;top:0;right:0;border-top:4px solid rgba(200,0,0,.9);border-right:4px solid rgba(200,0,0,.9);border-bottom:4px solid transparent;border-left:4px solid transparent;z-index:2;cursor:help}.gs-cell .gs-cell-label{font-size:10px;font-weight:500;font-style:normal;font-family:inherit;letter-spacing:.2px;line-height:1.4;position:absolute;top:0;right:0;background-color:var(--gs-accent,#2563eb);color:#fff;padding:1px 5px;border-bottom-left-radius:4px;display:none;opacity:.92}.gs-cell .gs-cell-inner-wrap{width:100%;height:100%;position:absolute;top:0;left:0}.gs-cell .gs-cell-inner{width:100%;height:100%;overflow:hidden;display:flex;box-sizing:border-box;border:none!important}.gs-cell .gs-cell-rendered{overflow:hidden;white-space:pre-wrap;cursor:cell;word-wrap:break-word;word-break:break-all;padding:0 6px;width:100%;height:100%}.gs-cell .gs-cell-rendered>*{position:relative}.gs-cell .gs-cell-rendered>.backface{z-index:0}.gs-cell .gs-autofill-drag{background-color:var(--gs-accent,#2563eb);position:absolute;width:7px;height:7px;bottom:0;right:0;cursor:crosshair;z-index:1}.gs-cell.gs-merged-host{z-index:1}.gs-cell.gs-merged-host.gs-selecting{background-color:transparent}.gs-cell.gs-merged-host.gs-selecting .gs-cell-inner-wrap{background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 7%,transparent)}.gs-cell.gs-merged-covered{z-index:0}.gs-th[data-x="1"] .gs-th-inner-wrap{border-left:none}.gs-th[data-y="1"] .gs-th-inner-wrap{border-top:none}.gs-formula-error-tooltip{position:fixed;background-color:rgba(35,8,8,.94);color:#fff;padding:6px 10px;border-radius:4px;border-left:3px solid rgba(220,50,50,.8);font-size:12px;line-height:1.5;max-width:260px;white-space:pre-wrap;word-break:break-word;box-shadow:0 3px 10px rgba(0,0,0,.4);z-index:100;pointer-events:none;letter-spacing:.3px}.gs-menu-modal{width:100%;height:100vh;z-index:12}.gs-label-input-label{font-size:13px;letter-spacing:1px}.gs-menu-divider{background-color:#aaa;padding:0;margin:5px 0;height:1px;list-style-type:none}.gs-menu-btn{position:absolute;background-color:rgba(128,128,128,.3);border:1px solid #ccc;border-radius:50%;cursor:pointer;font-size:12px;font-weight:700;line-height:1;color:#888;width:18px;height:18px;padding:0;display:flex;align-items:center;justify-content:center;opacity:0;transition:opacity .15s ease;z-index:2}.gs-context-menu{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;opacity:.9;transition:opacity .15s ease}.gs-context-menu:hover{opacity:1}.gs-context-menu .gs-menu-items{color:#555;margin:0;padding:0;min-width:250px}.gs-menu-item{padding:5px 10px;list-style-type:none;display:flex}.gs-menu-item.gs-enabled{cursor:pointer}.gs-menu-item.gs-enabled:hover{background-color:#eee}.gs-menu-item.gs-disabled{opacity:.5;cursor:not-allowed}.gs-menu-item .gs-menu-name{font-size:13px;letter-spacing:1px;flex:1}.gs-submenu-parent{position:relative;align-items:center}.gs-submenu-parent .gs-submenu-arrow{margin-left:8px;font-size:11px;opacity:.6}.gs-submenu-flyout{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;opacity:.9;transition:opacity .15s ease;min-width:200px;margin:0;color:#555;opacity:1;list-style-type:none}.gs-submenu-flyout:hover{opacity:1}.gs-menu-shortcut{font-size:10px;line-height:20px;color:#999}.gs-menu-shortcut:before{content:"( "}.gs-menu-shortcut:after{content:" )"}.gs-menu-shortcut .gs-menu-underline{text-decoration:underline}.gs-column-menu{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;opacity:.9;transition:opacity .15s ease}.gs-column-menu:hover{opacity:1}.gs-column-menu ul{color:#555;margin:0;padding:0;min-width:200px}.gs-column-menu .gs-column-menu-sort{align-items:center}.gs-column-menu .gs-column-menu-sort .gs-sort-buttons{display:flex;gap:4px;margin-left:auto}.gs-column-menu .gs-column-menu-sort .gs-sort-btn{font-size:12px;padding:4px 8px;border:1px solid transparent;border-radius:3px;background-color:rgba(180,180,180,.1);cursor:pointer;color:#555;font-weight:700;letter-spacing:.5px}.gs-column-menu .gs-column-menu-sort .gs-sort-btn:hover:not(:disabled){border-color:#555}.gs-column-menu .gs-column-menu-sort .gs-sort-btn:disabled{opacity:.5;cursor:not-allowed}.gs-column-menu .gs-column-menu-label{padding:5px 10px}.gs-column-menu .gs-label-input-row{display:flex;gap:4px;align-items:center}.gs-column-menu .gs-label-input{flex:1;font-size:13px;padding:4px 6px;border:none;border-bottom:1px solid #ccc;border-radius:0;outline:0;min-width:0;width:100px;background-color:transparent;box-shadow:none}.gs-column-menu .gs-label-input:focus{border-bottom-color:var(--gs-accent,#2563eb);outline:0;box-shadow:none}.gs-column-menu .gs-label-apply-btn{font-size:12px;padding:4px 8px;border:1px solid transparent;border-radius:3px;background-color:rgba(180,180,180,.1);cursor:pointer;color:#555;font-weight:700;letter-spacing:.5px}.gs-column-menu .gs-label-apply-btn:hover:not(:disabled){border-color:#555}.gs-column-menu .gs-label-apply-btn:disabled{opacity:.5;cursor:not-allowed}.gs-column-menu .gs-column-menu-filter{padding:5px 10px;list-style-type:none;font-size:13px}.gs-column-menu .gs-filter-header{display:flex;align-items:center;gap:8px}.gs-column-menu .gs-filter-header .gs-filter-add-btn{font-size:12px;padding:3px 9px;border:1px solid transparent;border-radius:3px;background-color:rgba(180,180,180,.1);cursor:pointer;color:#555;letter-spacing:1px}.gs-column-menu .gs-filter-header .gs-filter-add-btn:hover{border-color:#555}.gs-column-menu .gs-filter-mode-toggle{display:flex;gap:6px;margin-left:auto}.gs-column-menu .gs-filter-mode-toggle label{display:flex;align-items:center;gap:3px;font-size:11px;font-weight:700;letter-spacing:.5px;color:#888;cursor:pointer;user-select:none}.gs-column-menu .gs-filter-mode-toggle label input[type=radio]{margin:0;cursor:pointer}.gs-column-menu .gs-filter-mode-toggle label.gs-active{color:var(--gs-accent,#2563eb)}.gs-column-menu .gs-filter-mode-toggle.gs-disabled{opacity:.4;pointer-events:none}.gs-column-menu .gs-filter-conditions{display:flex;flex-direction:column;gap:5px;margin-top:6px;max-height:200px;overflow-y:auto}.gs-column-menu .gs-filter-condition-row{display:flex;gap:4px;align-items:normal}.gs-column-menu .gs-filter-method-select{font-size:12px;padding:4px 4px;border:none;border-bottom:1px solid #ccc;border-radius:0;outline:0;background-color:#fff;box-shadow:none;min-width:40px;max-width:80px;cursor:pointer}.gs-column-menu .gs-filter-method-select:focus{border-bottom-color:var(--gs-accent,#2563eb);outline:0;box-shadow:none}.gs-column-menu .gs-filter-value-input{flex:1;font-size:13px;padding:4px 6px;border:none;border-bottom:1px solid #ccc;border-radius:0;outline:0;min-width:0;width:80px;background-color:transparent;box-shadow:none}.gs-column-menu .gs-filter-value-input:focus{border-bottom-color:var(--gs-accent,#2563eb);outline:0;box-shadow:none}.gs-column-menu .gs-filter-remove-btn{font-size:12px;padding:0;border:none;border-radius:3px;background-color:transparent;cursor:pointer;color:#999;line-height:1;flex-shrink:0}.gs-column-menu .gs-filter-remove-btn:hover{color:#c33}.gs-column-menu .gs-filter-actions{display:flex;gap:4px;margin-top:10px;align-items:center}.gs-column-menu .gs-filter-actions .gs-filter-reset-all-btn{font-size:12px;padding:3px 9px;border:1px solid transparent;border-radius:3px;background-color:transparent;cursor:pointer;color:#c33;font-weight:700;letter-spacing:1px}.gs-column-menu .gs-filter-actions .gs-filter-reset-all-btn:hover{border-color:#c33}.gs-column-menu .gs-filter-actions .gs-filter-actions-right{display:flex;gap:4px;margin-left:auto}.gs-column-menu .gs-filter-actions .gs-filter-reset-btn{font-size:12px;padding:3px 9px;border:1px solid transparent;border-radius:3px;background-color:transparent;cursor:pointer;color:#e08000;font-weight:700;letter-spacing:1px}.gs-column-menu .gs-filter-actions .gs-filter-reset-btn:hover{border-color:#e08000}.gs-column-menu .gs-filter-actions .gs-filter-apply-btn{font-size:12px;padding:3px 6px;border:1px solid transparent;border-radius:3px;background-color:transparent;color:var(--gs-accent,#2563eb);cursor:pointer;font-weight:700;letter-spacing:1px}.gs-column-menu .gs-filter-actions .gs-filter-apply-btn:hover{border-color:var(--gs-accent,#2563eb)}.gs-column-menu-waiting{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:20px 30px;gap:12px;min-width:180px}.gs-column-menu-waiting .gs-waiting-message{font-size:13px;font-weight:700;color:#555;letter-spacing:.5px}.gs-column-menu-waiting .gs-waiting-spinner{width:24px;height:24px;border:3px solid #e0e0e0;border-top-color:var(--gs-accent,#2563eb);border-radius:50%;animation:spin .8s linear infinite}.gs-column-menu-waiting .gs-waiting-cancel-btn{font-size:12px;padding:4px 18px;border:1px solid #c33;border-radius:3px;background-color:transparent;color:#c33;cursor:pointer;font-weight:700;letter-spacing:1px}.gs-column-menu-waiting .gs-waiting-cancel-btn:hover{background-color:#c33;color:#fff}.gs-column-menu-btn{right:4px;top:50%;transform:translateY(-50%)}.gs-column-menu-btn.gs-filtered{opacity:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);border-color:var(--gs-accent,#2563eb);color:var(--gs-accent,#2563eb)}.gs-column-menu-btn.gs-active{opacity:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 18%,transparent);border-color:var(--gs-accent,#2563eb);color:var(--gs-accent,#2563eb)}.gs-th-top:hover .gs-column-menu-btn{opacity:1}.gs-row-menu{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;opacity:.9;transition:opacity .15s ease}.gs-row-menu:hover{opacity:1}.gs-row-menu ul{color:#555;margin:0;padding:0;min-width:200px}.gs-row-fixed-toggle{display:flex;align-items:center;gap:6px}.gs-row-fixed-check{font-size:12px;width:14px;text-align:center;color:transparent}.gs-row-fixed-check.gs-row-fixed-active{color:var(--gs-accent,#2563eb)}.gs-row-menu-btn{top:50%;transform:translateY(-50%);right:2px}.gs-row-menu-btn.gs-active{opacity:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 18%,transparent);border-color:var(--gs-accent,#2563eb);color:var(--gs-accent,#2563eb)}.gs-th-left:hover .gs-row-menu-btn{opacity:1}.gs-corner-menu-btn{bottom:2px;right:2px}.gs-corner-menu-btn:hover{opacity:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 18%,transparent);border-color:var(--gs-accent,#2563eb);color:var(--gs-accent,#2563eb)}.gs-th-left.gs-th-top:hover .gs-corner-menu-btn{opacity:1}.gs-editor-hl{padding:0 2px!important;position:absolute;font-family:monospace,Arial;font-size:12px;line-height:24px;letter-spacing:1px}.gs-formula-bar-editor-inner{position:relative;flex:1;min-width:0;display:flex;align-items:center}.gs-editor{opacity:0;z-index:-1}.gs-editor .gs-editor-inner{position:relative}.gs-editor .gs-editor-hl{box-sizing:content-box;border:solid 2px var(--gs-accent,#2563eb);margin:-2px -1px}.gs-editor textarea{width:100%;padding:0 2px!important;position:absolute;font-size:12px;font-family:monospace,Arial;line-height:24px;letter-spacing:1px;top:0;left:0;border:none;outline:0;background-color:transparent;color:transparent;resize:none;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;overflow:hidden;cursor:default;white-space:pre;height:auto}.gs-editor.gs-editing{z-index:11;opacity:1}.gs-editor.gs-editing .gs-cell-label{pointer-events:none;font-family:inherit;font-weight:500;position:absolute;top:0;right:0;margin-top:-17px;margin-right:-2px;padding:1px 5px;border-top-left-radius:4px;border-top-right-radius:4px;font-size:10px;background-color:var(--gs-accent,#2563eb);color:#fff;z-index:1}.gs-formula-bar{width:100%;position:relative;display:flex;align-items:stretch;box-sizing:border-box;border-style:solid;border-color:var(--gs-border,#e3e6ea);border-width:var(--gs-fb-bt,1px) var(--gs-fb-br,1px) var(--gs-fb-bb,1px) var(--gs-fb-bl,1px);padding:3px 6px;gap:6px}.gs-formula-bar .gs-selecting-address{display:flex;align-items:center;justify-content:center;min-width:38px;padding:0 4px;color:var(--gs-muted-fg,#6b7280);font-size:12px;font-variant-numeric:tabular-nums;text-align:center}.gs-formula-bar[data-spill=true]{background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 6%,var(--gs-header-bg,#f4f5f7))}.gs-formula-bar[data-spill=true] .gs-selecting-address{color:var(--gs-accent,#2563eb);font-style:italic}.gs-formula-bar[data-spill=true] .gs-selecting-address::after{content:"\2196";margin-left:2px;font-style:normal;font-size:9px}.gs-formula-bar .gs-fx{display:flex;align-items:center;justify-content:center;align-self:center;width:26px;height:18px;flex-shrink:0;color:var(--gs-muted-fg,#6b7280);font-style:italic;font-family:inherit;font-weight:400;text-align:center;font-size:13px;letter-spacing:.3px;border-radius:4px;background-color:color-mix(in srgb,var(--gs-fg,#1f2328) 6%,transparent)}.gs-formula-bar .gs-editor-hl{z-index:0;overflow-y:auto;box-sizing:border-box;white-space:pre-wrap;word-break:break-all;text-align:left;line-height:24px}.gs-formula-bar textarea{position:relative;z-index:1;width:100%;vertical-align:bottom;color:transparent;border:none;background-color:transparent;padding:0 2px;box-sizing:border-box;text-align:left;outline:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;font-size:12px;font-family:monospace,Arial;height:24px;line-height:24px;min-height:24px;letter-spacing:1px;resize:vertical;caret-color:var(--gs-fg,#1f2328);white-space:pre-wrap;word-break:break-all}.gs-token-type-INVALID_REF{color:red}.gs-token-type-VALUE.gs-token-entity-type-boolean,.gs-token-type-VALUE.gs-token-entity-type-number{color:#39f}.gs-token-type-VALUE.gs-token-entity-type-string{color:#090}.gs-editor-options{position:fixed;z-index:1000;padding:4px;background:var(--gs-bg,#fff);box-shadow:0 4px 12px rgba(0,0,0,.15);border:1px solid rgba(0,0,0,.1);border-radius:6px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;overflow:visible}.gs-editor-option{position:relative;cursor:pointer;list-style:none;padding:6px 12px;font-size:13px;border-radius:4px;color:#333;margin-bottom:2px}.gs-editor-option-content{display:flex;justify-content:space-between;width:100%;align-items:center}.gs-editor-option-tab{font-size:10px;color:#aaa;margin-left:8px;padding:2px 4px;border:1px solid #ddd;border-radius:3px;background:#f9f9f9}.gs-editor-option:last-child{margin-bottom:0}.gs-editor-option:hover{background-color:#f5f5f5}.gs-editor-option-selected{background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);color:var(--gs-accent,#2563eb);font-weight:500}.gs-editor-option-selected:hover{background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 18%,transparent)}.gs-fn-guide1{position:absolute;top:-4px;left:calc(100% + 8px);background:#fff;border:1px solid rgba(0,0,0,.1);box-shadow:0 4px 16px rgba(0,0,0,.12);border-radius:6px;padding:16px;width:280px;z-index:1000;cursor:default;white-space:normal;color:#333}.gs-fn-guide1-tooltip{margin-bottom:8px;line-height:1.4;font-size:13px}.gs-fn-guide1-example{font-family:monospace;font-weight:600;font-size:13px;margin-bottom:8px;color:#1a1a1a;background:#f5f5f5;padding:6px 8px;border-radius:4px;border:1px solid #eee;display:flex;align-items:center;gap:6px;flex-wrap:wrap}.gs-fn-guide1-desc{font-size:13px;color:#555;margin-bottom:12px;line-height:1.4}.gs-fn-guide1-desc p{margin:0 0 6px 0}.gs-fn-guide1-desc p:last-child{margin-bottom:0}.gs-fn-guide1-args{border-top:1px solid #eee;padding-top:10px}.gs-fn-guide1-arg{margin-bottom:6px;line-height:1.4;font-size:12px}.gs-fn-guide1-arg-name{font-weight:600;color:var(--gs-accent,#2563eb)}.gs-fn-guide1-arg-opt{color:#888;font-size:11px}.gs-fn-guide1-arg-iter{font-weight:600;color:var(--gs-accent,#2563eb)}.gs-fn-guide1-arg-type{color:var(--gs-accent,#2563eb);padding:0 4px;background:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);border-radius:3px;font-size:11px;margin:0 4px}.gs-fn-guide1-arg-desc{color:#666}.gs-fn-guide-category{position:absolute;top:-11px;right:8px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;font-size:11px;font-weight:600;letter-spacing:.5px;text-transform:uppercase;padding:2px 7px;border-radius:4px;background:#e8eaf6;color:#3949ab;border:1px solid #c5cae9;white-space:nowrap}.gs-fn-guide-category.gs-fn-guide-category-math{background:#e3f2fd;color:#1565c0;border-color:#bbdefb}.gs-fn-guide-category.gs-fn-guide-category-statistics{background:#e8f5e9;color:#2e7d32;border-color:#c8e6c9}.gs-fn-guide-category.gs-fn-guide-category-text{background:#fff8e1;color:#f57f17;border-color:#ffecb3}.gs-fn-guide-category.gs-fn-guide-category-time{background:#fce4ec;color:#880e4f;border-color:#f8bbd0}.gs-fn-guide-category.gs-fn-guide-category-lookup{background:#f3e5f5;color:#6a1b9a;border-color:#e1bee7}.gs-fn-guide-category.gs-fn-guide-category-logical{background:#e0f2f1;color:#00695c;border-color:#b2dfdb}.gs-fn-guide-category.gs-fn-guide-category-information{background:#e0f7fa;color:#006064;border-color:#b2ebf2}.gs-fn-guide-category.gs-fn-guide-category-finance{background:#fff3e0;color:#e65100;border-color:#ffe0b2}.gs-fn-guide-category.gs-fn-guide-category-engineering{background:#efebe9;color:#4e342e;border-color:#d7ccc8}.gs-fn-guide-category.gs-fn-guide-category-ai{background:#e8eaf6;color:#3949ab;border-color:#c5cae9}.gs-fn-guide-category.gs-fn-guide-category-other{background:#f5f5f5;color:#616161;border-color:#e0e0e0}.gs-editor-portal{display:contents}.gs-editor-portal[data-mode=dark] .gs-editor-options,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-options,.gs-editor[data-mode=dark] .gs-editor-options,.gs-editor[data-mode=inherit-dark] .gs-editor-options{background:#252526;border-color:#454545;box-shadow:0 4px 12px rgba(0,0,0,.5)}.gs-editor-portal[data-mode=dark] .gs-editor-option,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option,.gs-editor[data-mode=dark] .gs-editor-option,.gs-editor[data-mode=inherit-dark] .gs-editor-option{color:#ccc}.gs-editor-portal[data-mode=dark] .gs-editor-option:hover,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option:hover,.gs-editor[data-mode=dark] .gs-editor-option:hover,.gs-editor[data-mode=inherit-dark] .gs-editor-option:hover{background-color:#333}.gs-editor-portal[data-mode=dark] .gs-editor-option-selected,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option-selected,.gs-editor[data-mode=dark] .gs-editor-option-selected,.gs-editor[data-mode=inherit-dark] .gs-editor-option-selected{background-color:#094771;color:#fff}.gs-editor-portal[data-mode=dark] .gs-editor-option-selected:hover,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option-selected:hover,.gs-editor[data-mode=dark] .gs-editor-option-selected:hover,.gs-editor[data-mode=inherit-dark] .gs-editor-option-selected:hover{background-color:#0d5a8f}.gs-editor-portal[data-mode=dark] .gs-editor-option-tab,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option-tab,.gs-editor[data-mode=dark] .gs-editor-option-tab,.gs-editor[data-mode=inherit-dark] .gs-editor-option-tab{color:#777;background:#333;border-color:#444}.gs-editor-portal[data-mode=dark] .gs-fn-guide1,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1,.gs-editor[data-mode=dark] .gs-fn-guide1,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1{background:#252526;border-color:#454545;color:#ccc}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-example,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-example,.gs-editor[data-mode=dark] .gs-fn-guide1-example,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-example{background:#1e1e1e;border-color:#333;color:#d4d4d4}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-desc,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-desc,.gs-editor[data-mode=dark] .gs-fn-guide1-desc,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-desc{color:#aaa}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-args,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-args,.gs-editor[data-mode=dark] .gs-fn-guide1-args,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-args{border-color:#333}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-iter,.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-name,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-iter,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-name,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-iter,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-name,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-iter,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-name{color:#4fc1ff}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-opt,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-opt,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-opt,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-opt{color:#777}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-type,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-type,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-type,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-type{background:#094771;color:#4fc1ff}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-desc,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-desc,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-desc,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-desc{color:#999}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category,.gs-editor[data-mode=dark] .gs-fn-guide-category,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category{background:#2a2d3e;color:#7986cb;border-color:#3d4166}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-math,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-math,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-math,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-math{background:#0d2137;color:#64b5f6;border-color:#1a3a5c}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-statistics,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-statistics,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-statistics,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-statistics{background:#0d2218;color:#66bb6a;border-color:#1a3d2a}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-text,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-text,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-text,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-text{background:#2e2200;color:#ffd54f;border-color:#4d3900}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-time,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-time,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-time,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-time{background:#2d0d1e;color:#f48fb1;border-color:#4d1a33}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-lookup,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-lookup,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-lookup,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-lookup{background:#260d33;color:#ce93d8;border-color:#3d1a54}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-logical,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-logical,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-logical,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-logical{background:#0d2421;color:#4db6ac;border-color:#1a3d39}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-information,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-information,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-information,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-information{background:#0d2426;color:#4dd0e1;border-color:#1a3d40}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-finance,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-finance,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-finance,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-finance{background:#2e1500;color:#ffb74d;border-color:#4d2800}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-engineering,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-engineering,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-engineering,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-engineering{background:#1e1714;color:#bcaaa4;border-color:#332c28}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-ai,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-ai,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-ai,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-ai{background:#10142e;color:#7986cb;border-color:#232a52}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-other,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-other,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-other,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-other{background:#1e1e1e;color:#9e9e9e;border-color:#333}.gs-editor-portal[data-mode=dark] .gs-fn-guide2,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2,.gs-editor[data-mode=dark] .gs-fn-guide2,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2{background:#252526;border-color:#454545;box-shadow:0 4px 12px rgba(0,0,0,.5);color:#ccc}.gs-editor-portal[data-mode=dark] .gs-fn-guide2-name,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2-name,.gs-editor[data-mode=dark] .gs-fn-guide2-name,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2-name{color:#dfdbdb;background:#333;border-color:#444}.gs-editor-portal[data-mode=dark] .gs-fn-guide2 .gs-active-arg,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2 .gs-active-arg,.gs-editor[data-mode=dark] .gs-fn-guide2 .gs-active-arg,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2 .gs-active-arg{color:#fff;background-color:#094771}.gs-editor-portal[data-mode=dark] .gs-fn-guide2-arg-type,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2-arg-type,.gs-editor[data-mode=dark] .gs-fn-guide2-arg-type,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2-arg-type{background:#094771;color:#4fc1ff}.gs-editor-portal[data-mode=dark] .gs-fn-guide2-desc,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2-desc,.gs-editor[data-mode=dark] .gs-fn-guide2-desc,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2-desc{color:#aaa;border-top-color:#333}.gs-fn-guide2{position:fixed;left:0;background:#fff;border:1px solid rgba(0,0,0,.1);box-shadow:0 4px 16px rgba(0,0,0,.12);border-radius:6px;padding:12px 16px;width:280px;z-index:1000;cursor:default;white-space:normal;color:#333;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;transition:opacity .1s ease-in-out}.gs-fn-guide2.gs-fn-guide2-hidden{opacity:0!important;pointer-events:none!important}.gs-fn-guide2-name{font-family:monospace;font-weight:700;font-size:13px;color:#1a1a1a;background:#f5f5f5;padding:6px 8px;border-radius:4px;border:1px solid #eee;display:flex;align-items:center;gap:6px;flex-wrap:wrap;width:100%;box-sizing:border-box;margin-bottom:8px}.gs-fn-guide2-args-inline{font-size:13px;font-family:monospace;line-height:1.5;margin-bottom:8px;color:#666}.gs-fn-guide2-args-inline span{transition:all .2s ease-in-out}.gs-fn-guide2 .gs-active-arg{font-weight:700;color:var(--gs-accent,#2563eb);background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);padding:2px 4px;margin:0 -4px;border-radius:4px}.gs-fn-guide2-arg-type{color:var(--gs-accent,#2563eb);padding:0 4px;background:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);border-radius:3px;font-size:11px;margin:0 4px}.gs-fn-guide2-desc{font-size:12px;color:#555;line-height:1.4;border-top:1px solid #eee;padding-top:8px;margin-top:4px}.gs-fn-guide2-desc p{margin:0}.gs-fn-guide2-desc-more{font-style:italic;color:#888;margin-top:4px!important;font-size:11px}.gs-adjuster{padding:0}.gs-table{margin:0}.gs-tabular{overflow:auto;overflow-anchor:none;display:flex;box-sizing:border-box;position:relative}.gs-root1[data-matrix-align=both] .gs-tabular,.gs-root1[data-matrix-align=horizontal] .gs-tabular{justify-content:safe center}.gs-root1[data-matrix-align=both] .gs-tabular,.gs-root1[data-matrix-align=vertical] .gs-tabular{align-items:safe center}.gs-tabular-inner{flex:0 0 auto;position:relative;overflow:hidden;overflow:clip;box-sizing:border-box;border-right:solid var(--gs-mx-br,1px) var(--gs-border,#e3e6ea);border-bottom:solid var(--gs-mx-bb,1px) var(--gs-border,#e3e6ea)}.gs-tabular-inner>table{table-layout:fixed;border-collapse:collapse;border-spacing:0}.gs-ghost-layer{font-size:13px}.gs-ghost-layer .gs-ghost-panel{position:fixed;overflow:hidden;z-index:1000;cursor:crosshair}.gs-ghost-layer .gs-ghost-cell,.gs-ghost-layer .gs-ghost-th{position:absolute;box-sizing:border-box}.gs-ghost-layer .gs-ghost-cell{border:dashed 1px var(--gs-border,#e3e6ea);background-color:color-mix(in srgb,var(--gs-surface,#fff) 70%,transparent)}.gs-ghost-layer .gs-ghost-cell.gs-ghost-target{background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,var(--gs-surface,#fff));border-color:color-mix(in srgb,var(--gs-accent,#2563eb) 45%,transparent)}.gs-ghost-layer .gs-ghost-th{display:flex;align-items:center;justify-content:center;background-color:var(--gs-header-bg,#f6f7f9);color:var(--gs-header-fg,#555);border:dashed 1px var(--gs-border,#e3e6ea);opacity:.75}.gs-main[data-overflow-x=true] .gs-tabular-inner{border-right-width:0}.gs-main[data-overflow-y=true] .gs-tabular-inner{border-bottom-width:0}.gs-main::after{content:'';position:absolute;inset:0;pointer-events:none;z-index:3;border:0 solid var(--gs-border,#e3e6ea)}.gs-main[data-overflow-x=true]::after{border-right-width:var(--gs-mx-br,1px)}.gs-main[data-overflow-y=true]::after{border-bottom-width:var(--gs-mx-bb,1px)}.gs-th{z-index:2;padding:0;position:sticky;font-size:13px;font-weight:400;box-sizing:border-box;vertical-align:top}.gs-th .gs-resizer{position:absolute;border-color:transparent;box-sizing:border-box;z-index:2}.gs-th .gs-resizer:hover{background-color:var(--gs-accent,#2563eb)}.gs-th .gs-resizer.gs-protected{display:none}.gs-th-inner{height:100%;box-sizing:border-box;vertical-align:middle;overflow:hidden;display:flex;align-items:center;justify-content:center}.gs-th-inner-wrap{height:100%;box-sizing:border-box;background-color:transparent}.gs-th-top{top:0;overflow:hidden}.gs-th-top .gs-resizer{top:0;right:0;width:3px;cursor:e-resize}.gs-th-top .gs-resizer.gs-dragging{border-right-style:dotted;height:1000000px!important;cursor:e-resize}.gs-th-left{left:0;overflow:hidden;min-width:30px;border-top:solid 1px var(--gs-border,#e3e6ea)}.gs-th-left .gs-resizer{left:0;bottom:0;height:3px;cursor:n-resize}.gs-th-left .gs-resizer.gs-dragging{border-bottom-style:dotted;width:1000000px!important;cursor:n-resize}.gs-th-top.gs-th-left{top:0;left:0;z-index:3;border:none!important}.gs-th-left.gs-filter-fixed .gs-th-inner::before{content:'‹\00a0'}.gs-th-left.gs-sort-fixed .gs-th-inner::after{content:'\00a0›'}.gs-col-addr{position:absolute;top:2px;right:4px;font-size:9px;opacity:.5;line-height:1;letter-spacing:.3px;pointer-events:none}.gs-search-bar{width:100%;display:flex;align-items:center;padding:3px 0;border-top:solid 1px rgba(128,128,128,.3);border-left:solid 1px rgba(128,128,128,.3);border-right:solid 1px rgba(128,128,128,.3);border-bottom:solid 1px rgba(128,128,128,.3);box-sizing:border-box;background-color:rgba(200,50,0,.2)}.gs-search-bar.gs-search-found{background-color:rgba(0,200,100,.2)}.gs-search-bar .gs-search-bar-inner{border-left:solid 1px rgba(128,128,128,.5)}.gs-search-bar .gs-search-bar-icon{border-left:solid 1px rgba(128,128,128,.3);display:flex;align-items:center;justify-content:center;width:30px;flex-shrink:0}.gs-search-bar .gs-search-input-wrapper{flex-grow:1;position:relative;display:flex;align-items:center;height:100%}.gs-search-bar .gs-search-input-ghost{position:absolute;left:2px;right:2px;top:0;bottom:0;pointer-events:none;font-size:12px;font-family:monospace,Arial;line-height:24px;letter-spacing:1px;white-space:pre-wrap;word-break:break-all;color:transparent;overflow:hidden}.gs-search-bar .gs-search-input-ghost .gs-search-ghost-hint{color:#aaa}.gs-search-bar textarea{background-color:transparent;border:none;padding:0 2px;box-sizing:border-box;outline:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;font-size:12px;font-family:monospace,Arial;height:24px;line-height:24px;min-height:24px;letter-spacing:1px;caret-color:rgba(128,128,128);white-space:pre-wrap;word-break:break-all;flex-grow:1;width:100%;resize:none}.gs-search-progress{color:#999;font-size:13px;width:60px;flex-shrink:0;white-space:nowrap;text-align:center}.gs-search-close{cursor:pointer;display:flex;align-items:center;justify-content:center;width:24px;flex-shrink:0}.gs-search-buttons{display:flex;align-items:center;white-space:nowrap;flex-shrink:0}.gs-search-button{display:inline-flex;cursor:pointer;margin:0 2px}.gs-search-button span{display:inline-block;font-size:11px;padding:3px 5px;background-color:rgba(128,128,128,.1);border:1px solid rgba(128,128,128,.3);border-radius:3px;transition:all .15s ease;line-height:1}.gs-search-button span:hover{background-color:rgba(128,128,128,.2)}.gs-search-button span.gs-search-button-on{color:var(--gs-accent,#2563eb);background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 22%,transparent);border-color:var(--gs-accent,#2563eb)}.gs-search-range span{white-space:nowrap;font-family:monospace}@keyframes spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}.gs-loading-overlay{position:absolute;top:0;left:0;right:0;bottom:0;background:color-mix(in srgb,var(--gs-surface,#fff) 70%,transparent);display:flex;align-items:center;justify-content:center;z-index:100;pointer-events:all}.gs-loading-spinner{width:32px;height:32px;border:3px solid color-mix(in srgb,var(--gs-fg,#1f2328) 12%,transparent);border-top-color:var(--gs-accent,#2563eb);border-radius:50%;animation:spin .8s linear infinite}.gs-progress-overlay{position:absolute;top:0;left:0;right:0;bottom:0;z-index:100;pointer-events:all;display:flex;align-items:center;justify-content:center}.gs-progress-box{min-width:240px;padding:16px 18px;border-radius:8px;background:var(--gs-editor-surface,#fff);border:1px solid var(--gs-border,#e3e6ea);box-shadow:0 6px 24px rgba(0,0,0,.28);display:flex;flex-direction:column;gap:10px}.gs-progress-head{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--gs-fg,#1f2328)}.gs-progress-head .gs-loading-spinner{width:15px;height:15px;border-width:2px}.gs-progress-track{height:6px;border-radius:3px;overflow:hidden;background:color-mix(in srgb,var(--gs-fg,#1f2328) 12%,transparent)}.gs-progress-fill{height:100%;border-radius:3px;background:var(--gs-accent,#2563eb);transition:width .1s linear}@keyframes gs-pending-slide{0%{left:-40%}100%{left:100%}}@keyframes gs-pending-pulse{0%{left:0;width:0}50%{left:0;width:100%}100%{left:100%;width:0}}@keyframes gs-flash{0%{opacity:0}20%{opacity:1}100%{opacity:0}}.gs-flash-overlay{position:absolute;inset:0;pointer-events:none;z-index:9999;background:color-mix(in srgb,var(--gs-accent,#2563eb) 15%,transparent);opacity:0}.gs-flash-overlay--active{animation:gs-flash .6s ease-out forwards} \ No newline at end of file +.gs-root1{display:inline-block;position:relative;border-spacing:0;width:fit-content;max-width:100%;overflow:auto;font-family:"SF Pro Text","SF Pro Icons","Helvetica Neue",Helvetica,Arial,Meiryo,sans-serif;visibility:hidden;opacity:0}.gs-root1.gs-initialized{visibility:visible;opacity:1;transition:opacity .2s ease-in-out}.gs-root1 .gs-main{flex:1;max-width:100%;overflow:hidden;position:relative;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box}.gs-root1 .gs-resizing{width:100%;height:100%;position:absolute;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 8%,transparent);top:0;left:0;z-index:2}.gs-root1 .gs-line-horizontal{width:100%}.gs-root1 .gs-line-vertical{height:100%}.gs-root1 .gs-line{position:relative;top:0;left:0;border:dotted 1px var(--gs-accent,#2563eb);box-sizing:border-box}.gs-root1 .gs-line span{font-size:10px;padding:3px;background-color:var(--gs-accent,#2563eb);color:#fff;margin:0;position:absolute;top:0;left:0}.gs-root1 .gs-scroll-handle{width:100%;height:100%;cursor:cell}.gs-hidden{visibility:hidden;position:absolute;top:0;left:0;width:0;height:0;overflow:hidden;pointer-events:none;z-index:-1}.gs-fixed{position:fixed;top:0;left:0;z-index:1}:where(.gs-root1[data-mode=light],.gs-editor[data-mode=light]){--gs-fg:#1f2328;--gs-muted-fg:#6b7280;--gs-border:#e3e6ea;--gs-bg:rgba(128, 128, 128, 0.07);--gs-canvas:transparent;--gs-surface:#ffffff;--gs-editor-surface:#ffffff;--gs-header-bg:#f4f5f7;--gs-header-fg:#59616b;--gs-accent:#2563eb}.gs-root1{background-color:var(--gs-bg);color:var(--gs-fg)}.gs-root1 .gs-main{background-color:var(--gs-canvas)}.gs-root1 .gs-tabular{background-color:var(--gs-canvas)}.gs-root1 .gs-sheet-body-data{background-color:var(--gs-surface)}.gs-root1 .gs-formula-bar{background-color:var(--gs-header-bg)}.gs-root1 .gs-formula-bar-editor-inner{color:var(--gs-fg)}.gs-root1 .gs-cell{border:solid 1px var(--gs-border)}.gs-root1 .gs-adjuster{background-color:var(--gs-border)}.gs-root1 .gs-tabular-inner{background-color:var(--gs-border)}.gs-root1 .gs-large-editor textarea{color:var(--gs-fg);caret-color:var(--gs-fg)}.gs-root1 .gs-th{background-color:var(--gs-header-bg);color:var(--gs-header-fg)}.gs-root1 .gs-th-top{border-left:solid 1px var(--gs-border)}.gs-root1 .gs-th-top .gs-th-inner{border-top:solid var(--gs-mx-bt,1px) var(--gs-border)}.gs-root1 .gs-th-left{border-top:solid 1px var(--gs-border)}.gs-root1 .gs-th-left .gs-th-inner{border-left:solid var(--gs-mx-bl,1px) var(--gs-border)}.gs-root1 .gs-search-bar{color:color-mix(in srgb,var(--gs-fg) 40%,transparent)}.gs-root1 .gs-search-bar textarea{color:var(--gs-fg);caret-color:var(--gs-fg)}.gs-editor.gs-editing textarea{caret-color:var(--gs-fg)}.gs-editor.gs-editing .gs-editor-hl{background-color:var(--gs-editor-surface);color:var(--gs-fg)}.gs-editor .gs-editor-options{color:var(--gs-fg);background-color:var(--gs-editor-surface);border:solid 1px var(--gs-border)}:where(.gs-root1[data-mode=dark],.gs-editor[data-mode=dark]){--gs-fg:#e4e6e9;--gs-muted-fg:#8b9096;--gs-border:#2c2f34;--gs-bg:rgba(128, 128, 128, 0.07);--gs-canvas:transparent;--gs-surface:#1c1e21;--gs-editor-surface:#1c1e21;--gs-header-bg:#212327;--gs-header-fg:#a6abb2;--gs-accent:#3b82f6}:where(.gs-root1[data-mode=auto],.gs-editor[data-mode=auto]){--gs-fg:#1f2328;--gs-muted-fg:#6b7280;--gs-border:#e3e6ea;--gs-bg:rgba(128, 128, 128, 0.07);--gs-canvas:transparent;--gs-surface:#ffffff;--gs-editor-surface:#ffffff;--gs-header-bg:#f4f5f7;--gs-header-fg:#59616b;--gs-accent:#2563eb}@media (prefers-color-scheme:dark){:where(.gs-root1[data-mode=auto],.gs-editor[data-mode=auto]){--gs-fg:#e4e6e9;--gs-muted-fg:#8b9096;--gs-border:#2c2f34;--gs-bg:rgba(128, 128, 128, 0.07);--gs-canvas:transparent;--gs-surface:#1c1e21;--gs-editor-surface:#1c1e21;--gs-header-bg:#212327;--gs-header-fg:#a6abb2;--gs-accent:#3b82f6}}:where(.gs-root1[data-mode=inherit-light],.gs-editor[data-mode=inherit-light]){--gs-fg:#1f2328;--gs-muted-fg:#6b7280;--gs-border:#e3e6ea;--gs-bg:rgba(128, 128, 128, 0.07);--gs-surface:#ffffff;--gs-editor-surface:#ffffff;--gs-header-bg:#f4f5f7;--gs-header-fg:#59616b;--gs-accent:#2563eb;--gs-bg:transparent;--gs-canvas:transparent;--gs-surface:transparent;--gs-header-bg:transparent}:where(.gs-root1[data-mode=inherit-dark],.gs-editor[data-mode=inherit-dark]){--gs-fg:#e4e6e9;--gs-muted-fg:#8b9096;--gs-border:#2c2f34;--gs-bg:rgba(128, 128, 128, 0.07);--gs-surface:#1c1e21;--gs-editor-surface:#1c1e21;--gs-header-bg:#212327;--gs-header-fg:#a6abb2;--gs-accent:#3b82f6;--gs-bg:transparent;--gs-canvas:transparent;--gs-surface:transparent;--gs-header-bg:transparent}.gs-root1[data-mode=inherit-dark] .gs-adjuster,.gs-root1[data-mode=inherit-dark] .gs-tabular-inner,.gs-root1[data-mode=inherit-light] .gs-adjuster,.gs-root1[data-mode=inherit-light] .gs-tabular-inner{background-color:transparent}.gs-root1[data-mode=inherit-light] .gs-th{background-color:rgba(128,128,128,.1);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}.gs-root1[data-mode=inherit-dark] .gs-th{background-color:rgba(128,128,128,.1);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}.gs-root1[data-gridlines=horizontal] .gs-cell{border-left-color:transparent;border-right-color:transparent}.gs-root1[data-gridlines=none] .gs-cell{border-color:transparent}.gs-root1[data-density=comfortable] .gs-cell-rendered{padding:0 10px}.gs-cell{transition:border-color .2s ease;padding:0;margin:0;box-sizing:border-box;position:relative;font-size:13px;letter-spacing:1px;line-height:24px;cursor:cell;user-select:none;-webkit-user-select:none;-moz-user-select:none}.gs-cell.gs-copying textarea:focus{outline:solid 1px var(--gs-accent,#2563eb)}.gs-cell.gs-selecting{z-index:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 7%,transparent)}.gs-cell.gs-selecting .gs-cell-label{display:block}.gs-cell.gs-choosing{margin-top:-1px;margin-left:-1px;z-index:1}.gs-cell.gs-choosing.gs-editing{color:transparent}.gs-cell.gs-choosing .gs-cell-label{display:block}.gs-cell.gs-pending .gs-cell-rendered{position:relative;overflow:hidden}.gs-cell.gs-pending .gs-cell-rendered::after{content:'';position:absolute;bottom:0;left:0;height:4px;width:40%;border-radius:1px;background:color-mix(in srgb,var(--gs-accent,#2563eb) 65%,transparent);animation:gs-pending-slide 1.4s ease-in-out infinite}.gs-cell .gs-formula-error-triangle{position:absolute;top:0;right:0;border-top:4px solid rgba(200,0,0,.9);border-right:4px solid rgba(200,0,0,.9);border-bottom:4px solid transparent;border-left:4px solid transparent;z-index:2;cursor:help}.gs-cell .gs-cell-label{font-size:10px;font-weight:500;font-style:normal;font-family:inherit;letter-spacing:.2px;line-height:1.4;position:absolute;top:0;right:0;background-color:var(--gs-accent,#2563eb);color:#fff;padding:1px 5px;border-bottom-left-radius:4px;display:none;opacity:.92}.gs-cell .gs-cell-inner-wrap{width:100%;height:100%;position:absolute;top:0;left:0}.gs-cell .gs-cell-inner{width:100%;height:100%;overflow:hidden;display:flex;box-sizing:border-box;border:none!important}.gs-cell .gs-cell-rendered{overflow:hidden;white-space:pre-wrap;cursor:cell;word-wrap:break-word;word-break:break-all;padding:0 6px;width:100%;height:100%}.gs-cell .gs-cell-rendered>*{position:relative}.gs-cell .gs-cell-rendered>.backface{z-index:0}.gs-cell .gs-autofill-drag{background-color:var(--gs-accent,#2563eb);position:absolute;width:7px;height:7px;bottom:0;right:0;cursor:crosshair;z-index:1}.gs-cell.gs-merged-host{z-index:1}.gs-cell.gs-merged-host.gs-selecting{background-color:transparent}.gs-cell.gs-merged-host.gs-selecting .gs-cell-inner-wrap{background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 7%,transparent)}.gs-cell.gs-merged-covered{z-index:0}.gs-th[data-x="1"] .gs-th-inner-wrap{border-left:none}.gs-th[data-y="1"] .gs-th-inner-wrap{border-top:none}.gs-formula-error-tooltip{position:fixed;background-color:rgba(35,8,8,.94);color:#fff;padding:6px 10px;border-radius:4px;border-left:3px solid rgba(220,50,50,.8);font-size:12px;line-height:1.5;max-width:260px;white-space:pre-wrap;word-break:break-word;box-shadow:0 3px 10px rgba(0,0,0,.4);z-index:100;pointer-events:none;letter-spacing:.3px}.gs-menu-modal{width:100%;height:100vh;z-index:12}.gs-label-input-label{font-size:13px;letter-spacing:1px}.gs-menu-divider{background-color:#aaa;padding:0;margin:5px 0;height:1px;list-style-type:none}.gs-menu-btn{position:absolute;background-color:rgba(128,128,128,.3);border:1px solid #ccc;border-radius:50%;cursor:pointer;font-size:12px;font-weight:700;line-height:1;color:#888;width:18px;height:18px;padding:0;display:flex;align-items:center;justify-content:center;opacity:0;transition:opacity .15s ease;z-index:2}.gs-context-menu{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;opacity:.9;transition:opacity .15s ease}.gs-context-menu:hover{opacity:1}.gs-context-menu .gs-menu-items{color:#555;margin:0;padding:0;min-width:250px}.gs-menu-item{padding:5px 10px;list-style-type:none;display:flex}.gs-menu-item.gs-enabled{cursor:pointer}.gs-menu-item.gs-enabled:hover{background-color:#eee}.gs-menu-item.gs-disabled{opacity:.5;cursor:not-allowed}.gs-menu-item .gs-menu-name{font-size:13px;letter-spacing:1px;flex:1}.gs-submenu-parent{position:relative;align-items:center}.gs-submenu-parent .gs-submenu-arrow{margin-left:8px;font-size:11px;opacity:.6}.gs-submenu-flyout{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;opacity:.9;transition:opacity .15s ease;min-width:200px;margin:0;color:#555;opacity:1;list-style-type:none}.gs-submenu-flyout:hover{opacity:1}.gs-menu-shortcut{font-size:10px;line-height:20px;color:#999}.gs-menu-shortcut:before{content:"( "}.gs-menu-shortcut:after{content:" )"}.gs-menu-shortcut .gs-menu-underline{text-decoration:underline}.gs-column-menu{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;opacity:.9;transition:opacity .15s ease}.gs-column-menu:hover{opacity:1}.gs-column-menu ul{color:#555;margin:0;padding:0;min-width:200px}.gs-column-menu .gs-column-menu-sort{align-items:center}.gs-column-menu .gs-column-menu-sort .gs-sort-buttons{display:flex;gap:4px;margin-left:auto}.gs-column-menu .gs-column-menu-sort .gs-sort-btn{font-size:12px;padding:4px 8px;border:1px solid transparent;border-radius:3px;background-color:rgba(180,180,180,.1);cursor:pointer;color:#555;font-weight:700;letter-spacing:.5px}.gs-column-menu .gs-column-menu-sort .gs-sort-btn:hover:not(:disabled){border-color:#555}.gs-column-menu .gs-column-menu-sort .gs-sort-btn:disabled{opacity:.5;cursor:not-allowed}.gs-column-menu .gs-column-menu-label{padding:5px 10px}.gs-column-menu .gs-label-input-row{display:flex;gap:4px;align-items:center}.gs-column-menu .gs-label-input{flex:1;font-size:13px;padding:4px 6px;border:none;border-bottom:1px solid #ccc;border-radius:0;outline:0;min-width:0;width:100px;background-color:transparent;box-shadow:none}.gs-column-menu .gs-label-input:focus{border-bottom-color:var(--gs-accent,#2563eb);outline:0;box-shadow:none}.gs-column-menu .gs-label-apply-btn{font-size:12px;padding:4px 8px;border:1px solid transparent;border-radius:3px;background-color:rgba(180,180,180,.1);cursor:pointer;color:#555;font-weight:700;letter-spacing:.5px}.gs-column-menu .gs-label-apply-btn:hover:not(:disabled){border-color:#555}.gs-column-menu .gs-label-apply-btn:disabled{opacity:.5;cursor:not-allowed}.gs-column-menu .gs-column-menu-filter{padding:5px 10px;list-style-type:none;font-size:13px}.gs-column-menu .gs-filter-header{display:flex;align-items:center;gap:8px}.gs-column-menu .gs-filter-header .gs-filter-add-btn{font-size:12px;padding:3px 9px;border:1px solid transparent;border-radius:3px;background-color:rgba(180,180,180,.1);cursor:pointer;color:#555;letter-spacing:1px}.gs-column-menu .gs-filter-header .gs-filter-add-btn:hover{border-color:#555}.gs-column-menu .gs-filter-mode-toggle{display:flex;gap:6px;margin-left:auto}.gs-column-menu .gs-filter-mode-toggle label{display:flex;align-items:center;gap:3px;font-size:11px;font-weight:700;letter-spacing:.5px;color:#888;cursor:pointer;user-select:none}.gs-column-menu .gs-filter-mode-toggle label input[type=radio]{margin:0;cursor:pointer}.gs-column-menu .gs-filter-mode-toggle label.gs-active{color:var(--gs-accent,#2563eb)}.gs-column-menu .gs-filter-mode-toggle.gs-disabled{opacity:.4;pointer-events:none}.gs-column-menu .gs-filter-conditions{display:flex;flex-direction:column;gap:5px;margin-top:6px;max-height:200px;overflow-y:auto}.gs-column-menu .gs-filter-condition-row{display:flex;gap:4px;align-items:normal}.gs-column-menu .gs-filter-method-select{font-size:12px;padding:4px 4px;border:none;border-bottom:1px solid #ccc;border-radius:0;outline:0;background-color:#fff;box-shadow:none;min-width:40px;max-width:80px;cursor:pointer}.gs-column-menu .gs-filter-method-select:focus{border-bottom-color:var(--gs-accent,#2563eb);outline:0;box-shadow:none}.gs-column-menu .gs-filter-value-input{flex:1;font-size:13px;padding:4px 6px;border:none;border-bottom:1px solid #ccc;border-radius:0;outline:0;min-width:0;width:80px;background-color:transparent;box-shadow:none}.gs-column-menu .gs-filter-value-input:focus{border-bottom-color:var(--gs-accent,#2563eb);outline:0;box-shadow:none}.gs-column-menu .gs-filter-remove-btn{font-size:12px;padding:0;border:none;border-radius:3px;background-color:transparent;cursor:pointer;color:#999;line-height:1;flex-shrink:0}.gs-column-menu .gs-filter-remove-btn:hover{color:#c33}.gs-column-menu .gs-filter-actions{display:flex;gap:4px;margin-top:10px;align-items:center}.gs-column-menu .gs-filter-actions .gs-filter-reset-all-btn{font-size:12px;padding:3px 9px;border:1px solid transparent;border-radius:3px;background-color:transparent;cursor:pointer;color:#c33;font-weight:700;letter-spacing:1px}.gs-column-menu .gs-filter-actions .gs-filter-reset-all-btn:hover{border-color:#c33}.gs-column-menu .gs-filter-actions .gs-filter-actions-right{display:flex;gap:4px;margin-left:auto}.gs-column-menu .gs-filter-actions .gs-filter-reset-btn{font-size:12px;padding:3px 9px;border:1px solid transparent;border-radius:3px;background-color:transparent;cursor:pointer;color:#e08000;font-weight:700;letter-spacing:1px}.gs-column-menu .gs-filter-actions .gs-filter-reset-btn:hover{border-color:#e08000}.gs-column-menu .gs-filter-actions .gs-filter-apply-btn{font-size:12px;padding:3px 6px;border:1px solid transparent;border-radius:3px;background-color:transparent;color:var(--gs-accent,#2563eb);cursor:pointer;font-weight:700;letter-spacing:1px}.gs-column-menu .gs-filter-actions .gs-filter-apply-btn:hover{border-color:var(--gs-accent,#2563eb)}.gs-column-menu-waiting{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:20px 30px;gap:12px;min-width:180px}.gs-column-menu-waiting .gs-waiting-message{font-size:13px;font-weight:700;color:#555;letter-spacing:.5px}.gs-column-menu-waiting .gs-waiting-spinner{width:24px;height:24px;border:3px solid #e0e0e0;border-top-color:var(--gs-accent,#2563eb);border-radius:50%;animation:spin .8s linear infinite}.gs-column-menu-waiting .gs-waiting-cancel-btn{font-size:12px;padding:4px 18px;border:1px solid #c33;border-radius:3px;background-color:transparent;color:#c33;cursor:pointer;font-weight:700;letter-spacing:1px}.gs-column-menu-waiting .gs-waiting-cancel-btn:hover{background-color:#c33;color:#fff}.gs-column-menu-btn{right:4px;top:50%;transform:translateY(-50%)}.gs-column-menu-btn.gs-filtered{opacity:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);border-color:var(--gs-accent,#2563eb);color:var(--gs-accent,#2563eb)}.gs-column-menu-btn.gs-active{opacity:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 18%,transparent);border-color:var(--gs-accent,#2563eb);color:var(--gs-accent,#2563eb)}.gs-th-top:hover .gs-column-menu-btn{opacity:1}.gs-row-menu{z-index:12;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;opacity:.9;transition:opacity .15s ease}.gs-row-menu:hover{opacity:1}.gs-row-menu ul{color:#555;margin:0;padding:0;min-width:200px}.gs-row-fixed-toggle{display:flex;align-items:center;gap:6px}.gs-row-fixed-check{font-size:12px;width:14px;text-align:center;color:transparent}.gs-row-fixed-check.gs-row-fixed-active{color:var(--gs-accent,#2563eb)}.gs-row-menu-btn{top:50%;transform:translateY(-50%);right:2px}.gs-row-menu-btn.gs-active{opacity:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 18%,transparent);border-color:var(--gs-accent,#2563eb);color:var(--gs-accent,#2563eb)}.gs-th-left:hover .gs-row-menu-btn{opacity:1}.gs-corner-menu-btn{bottom:2px;right:2px}.gs-corner-menu-btn:hover{opacity:1;background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 18%,transparent);border-color:var(--gs-accent,#2563eb);color:var(--gs-accent,#2563eb)}.gs-th-left.gs-th-top:hover .gs-corner-menu-btn{opacity:1}.gs-editor-hl{padding:0 2px!important;position:absolute;font-family:monospace,Arial;font-size:12px;line-height:24px;letter-spacing:1px}.gs-formula-bar-editor-inner{position:relative;flex:1;min-width:0;display:flex;align-items:center}.gs-editor{opacity:0;z-index:-1}.gs-editor .gs-editor-inner{position:relative}.gs-editor .gs-editor-hl{box-sizing:content-box;border:solid 2px var(--gs-accent,#2563eb);margin:-2px -1px}.gs-editor textarea{width:100%;padding:0 2px!important;position:absolute;font-size:12px;font-family:monospace,Arial;line-height:24px;letter-spacing:1px;top:0;left:0;border:none;outline:0;background-color:transparent;color:transparent;resize:none;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;overflow:hidden;cursor:default;white-space:pre;height:auto}.gs-editor.gs-editing{z-index:11;opacity:1}.gs-editor.gs-editing .gs-cell-label{pointer-events:none;font-family:inherit;font-weight:500;position:absolute;top:0;right:0;margin-top:-17px;margin-right:-2px;padding:1px 5px;border-top-left-radius:4px;border-top-right-radius:4px;font-size:10px;background-color:var(--gs-accent,#2563eb);color:#fff;z-index:1}.gs-formula-bar{width:100%;position:relative;display:flex;align-items:stretch;box-sizing:border-box;border-style:solid;border-color:var(--gs-border,#e3e6ea);border-width:var(--gs-fb-bt,1px) var(--gs-fb-br,1px) var(--gs-fb-bb,1px) var(--gs-fb-bl,1px);padding:3px 6px;gap:6px}.gs-formula-bar .gs-selecting-address{display:flex;align-items:center;justify-content:center;min-width:38px;padding:0 4px;color:var(--gs-muted-fg,#6b7280);font-size:12px;font-variant-numeric:tabular-nums;text-align:center}.gs-formula-bar[data-spill=true]{background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 6%,var(--gs-header-bg,#f4f5f7))}.gs-formula-bar[data-spill=true] .gs-selecting-address{color:var(--gs-accent,#2563eb);font-style:italic}.gs-formula-bar[data-spill=true] .gs-selecting-address::after{content:"\2196";margin-left:2px;font-style:normal;font-size:9px}.gs-formula-bar .gs-fx{display:flex;align-items:center;justify-content:center;align-self:center;width:26px;height:18px;flex-shrink:0;color:var(--gs-muted-fg,#6b7280);font-style:italic;font-family:inherit;font-weight:400;text-align:center;font-size:13px;letter-spacing:.3px;border-radius:4px;background-color:color-mix(in srgb,var(--gs-fg,#1f2328) 6%,transparent)}.gs-formula-bar .gs-editor-hl{z-index:0;overflow-y:auto;box-sizing:border-box;white-space:pre-wrap;word-break:break-all;text-align:left;line-height:24px}.gs-formula-bar textarea{position:relative;z-index:1;width:100%;vertical-align:bottom;color:transparent;border:none;background-color:transparent;padding:0 2px;box-sizing:border-box;text-align:left;outline:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;font-size:12px;font-family:monospace,Arial;height:24px;line-height:24px;min-height:24px;letter-spacing:1px;resize:vertical;caret-color:var(--gs-fg,#1f2328);white-space:pre-wrap;word-break:break-all}.gs-token-type-INVALID_REF{color:red}.gs-token-type-VALUE.gs-token-entity-type-boolean,.gs-token-type-VALUE.gs-token-entity-type-number{color:#39f}.gs-token-type-VALUE.gs-token-entity-type-string{color:#090}.gs-editor-options{position:fixed;z-index:1000;padding:4px;background:var(--gs-bg,#fff);box-shadow:0 4px 12px rgba(0,0,0,.15);border:1px solid rgba(0,0,0,.1);border-radius:6px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;overflow:visible}.gs-editor-option{position:relative;cursor:pointer;list-style:none;padding:6px 12px;font-size:13px;border-radius:4px;color:#333;margin-bottom:2px}.gs-editor-option-content{display:flex;justify-content:space-between;width:100%;align-items:center}.gs-editor-option-tab{font-size:10px;color:#aaa;margin-left:8px;padding:2px 4px;border:1px solid #ddd;border-radius:3px;background:#f9f9f9}.gs-editor-option:last-child{margin-bottom:0}.gs-editor-option:hover{background-color:#f5f5f5}.gs-editor-option-selected{background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);color:var(--gs-accent,#2563eb);font-weight:500}.gs-editor-option-selected:hover{background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 18%,transparent)}.gs-fn-guide1{position:absolute;top:-4px;left:calc(100% + 8px);background:#fff;border:1px solid rgba(0,0,0,.1);box-shadow:0 4px 16px rgba(0,0,0,.12);border-radius:6px;padding:16px;width:280px;z-index:1000;cursor:default;white-space:normal;color:#333}.gs-fn-guide1-tooltip{margin-bottom:8px;line-height:1.4;font-size:13px}.gs-fn-guide1-example{font-family:monospace;font-weight:600;font-size:13px;margin-bottom:8px;color:#1a1a1a;background:#f5f5f5;padding:6px 8px;border-radius:4px;border:1px solid #eee;display:flex;align-items:center;gap:6px;flex-wrap:wrap}.gs-fn-guide1-desc{font-size:13px;color:#555;margin-bottom:12px;line-height:1.4}.gs-fn-guide1-desc p{margin:0 0 6px 0}.gs-fn-guide1-desc p:last-child{margin-bottom:0}.gs-fn-guide1-args{border-top:1px solid #eee;padding-top:10px}.gs-fn-guide1-arg{margin-bottom:6px;line-height:1.4;font-size:12px}.gs-fn-guide1-arg-name{font-weight:600;color:var(--gs-accent,#2563eb)}.gs-fn-guide1-arg-opt{color:#888;font-size:11px}.gs-fn-guide1-arg-iter{font-weight:600;color:var(--gs-accent,#2563eb)}.gs-fn-guide1-arg-type{color:var(--gs-accent,#2563eb);padding:0 4px;background:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);border-radius:3px;font-size:11px;margin:0 4px}.gs-fn-guide1-arg-desc{color:#666}.gs-fn-guide-category{position:absolute;top:-11px;right:8px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;font-size:11px;font-weight:600;letter-spacing:.5px;text-transform:uppercase;padding:2px 7px;border-radius:4px;background:#e8eaf6;color:#3949ab;border:1px solid #c5cae9;white-space:nowrap}.gs-fn-guide-category.gs-fn-guide-category-math{background:#e3f2fd;color:#1565c0;border-color:#bbdefb}.gs-fn-guide-category.gs-fn-guide-category-statistics{background:#e8f5e9;color:#2e7d32;border-color:#c8e6c9}.gs-fn-guide-category.gs-fn-guide-category-text{background:#fff8e1;color:#f57f17;border-color:#ffecb3}.gs-fn-guide-category.gs-fn-guide-category-time{background:#fce4ec;color:#880e4f;border-color:#f8bbd0}.gs-fn-guide-category.gs-fn-guide-category-lookup{background:#f3e5f5;color:#6a1b9a;border-color:#e1bee7}.gs-fn-guide-category.gs-fn-guide-category-logical{background:#e0f2f1;color:#00695c;border-color:#b2dfdb}.gs-fn-guide-category.gs-fn-guide-category-information{background:#e0f7fa;color:#006064;border-color:#b2ebf2}.gs-fn-guide-category.gs-fn-guide-category-finance{background:#fff3e0;color:#e65100;border-color:#ffe0b2}.gs-fn-guide-category.gs-fn-guide-category-engineering{background:#efebe9;color:#4e342e;border-color:#d7ccc8}.gs-fn-guide-category.gs-fn-guide-category-ai{background:#e8eaf6;color:#3949ab;border-color:#c5cae9}.gs-fn-guide-category.gs-fn-guide-category-other{background:#f5f5f5;color:#616161;border-color:#e0e0e0}.gs-editor-portal{display:contents}.gs-editor-portal[data-mode=dark] .gs-editor-options,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-options,.gs-editor[data-mode=dark] .gs-editor-options,.gs-editor[data-mode=inherit-dark] .gs-editor-options{background:#252526;border-color:#454545;box-shadow:0 4px 12px rgba(0,0,0,.5)}.gs-editor-portal[data-mode=dark] .gs-editor-option,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option,.gs-editor[data-mode=dark] .gs-editor-option,.gs-editor[data-mode=inherit-dark] .gs-editor-option{color:#ccc}.gs-editor-portal[data-mode=dark] .gs-editor-option:hover,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option:hover,.gs-editor[data-mode=dark] .gs-editor-option:hover,.gs-editor[data-mode=inherit-dark] .gs-editor-option:hover{background-color:#333}.gs-editor-portal[data-mode=dark] .gs-editor-option-selected,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option-selected,.gs-editor[data-mode=dark] .gs-editor-option-selected,.gs-editor[data-mode=inherit-dark] .gs-editor-option-selected{background-color:#094771;color:#fff}.gs-editor-portal[data-mode=dark] .gs-editor-option-selected:hover,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option-selected:hover,.gs-editor[data-mode=dark] .gs-editor-option-selected:hover,.gs-editor[data-mode=inherit-dark] .gs-editor-option-selected:hover{background-color:#0d5a8f}.gs-editor-portal[data-mode=dark] .gs-editor-option-tab,.gs-editor-portal[data-mode=inherit-dark] .gs-editor-option-tab,.gs-editor[data-mode=dark] .gs-editor-option-tab,.gs-editor[data-mode=inherit-dark] .gs-editor-option-tab{color:#777;background:#333;border-color:#444}.gs-editor-portal[data-mode=dark] .gs-fn-guide1,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1,.gs-editor[data-mode=dark] .gs-fn-guide1,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1{background:#252526;border-color:#454545;color:#ccc}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-example,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-example,.gs-editor[data-mode=dark] .gs-fn-guide1-example,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-example{background:#1e1e1e;border-color:#333;color:#d4d4d4}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-desc,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-desc,.gs-editor[data-mode=dark] .gs-fn-guide1-desc,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-desc{color:#aaa}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-args,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-args,.gs-editor[data-mode=dark] .gs-fn-guide1-args,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-args{border-color:#333}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-iter,.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-name,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-iter,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-name,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-iter,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-name,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-iter,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-name{color:#4fc1ff}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-opt,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-opt,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-opt,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-opt{color:#777}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-type,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-type,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-type,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-type{background:#094771;color:#4fc1ff}.gs-editor-portal[data-mode=dark] .gs-fn-guide1-arg-desc,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide1-arg-desc,.gs-editor[data-mode=dark] .gs-fn-guide1-arg-desc,.gs-editor[data-mode=inherit-dark] .gs-fn-guide1-arg-desc{color:#999}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category,.gs-editor[data-mode=dark] .gs-fn-guide-category,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category{background:#2a2d3e;color:#7986cb;border-color:#3d4166}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-math,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-math,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-math,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-math{background:#0d2137;color:#64b5f6;border-color:#1a3a5c}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-statistics,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-statistics,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-statistics,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-statistics{background:#0d2218;color:#66bb6a;border-color:#1a3d2a}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-text,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-text,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-text,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-text{background:#2e2200;color:#ffd54f;border-color:#4d3900}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-time,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-time,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-time,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-time{background:#2d0d1e;color:#f48fb1;border-color:#4d1a33}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-lookup,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-lookup,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-lookup,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-lookup{background:#260d33;color:#ce93d8;border-color:#3d1a54}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-logical,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-logical,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-logical,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-logical{background:#0d2421;color:#4db6ac;border-color:#1a3d39}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-information,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-information,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-information,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-information{background:#0d2426;color:#4dd0e1;border-color:#1a3d40}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-finance,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-finance,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-finance,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-finance{background:#2e1500;color:#ffb74d;border-color:#4d2800}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-engineering,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-engineering,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-engineering,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-engineering{background:#1e1714;color:#bcaaa4;border-color:#332c28}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-ai,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-ai,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-ai,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-ai{background:#10142e;color:#7986cb;border-color:#232a52}.gs-editor-portal[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-other,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-other,.gs-editor[data-mode=dark] .gs-fn-guide-category.gs-fn-guide-category-other,.gs-editor[data-mode=inherit-dark] .gs-fn-guide-category.gs-fn-guide-category-other{background:#1e1e1e;color:#9e9e9e;border-color:#333}.gs-editor-portal[data-mode=dark] .gs-fn-guide2,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2,.gs-editor[data-mode=dark] .gs-fn-guide2,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2{background:#252526;border-color:#454545;box-shadow:0 4px 12px rgba(0,0,0,.5);color:#ccc}.gs-editor-portal[data-mode=dark] .gs-fn-guide2-name,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2-name,.gs-editor[data-mode=dark] .gs-fn-guide2-name,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2-name{color:#dfdbdb;background:#333;border-color:#444}.gs-editor-portal[data-mode=dark] .gs-fn-guide2 .gs-active-arg,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2 .gs-active-arg,.gs-editor[data-mode=dark] .gs-fn-guide2 .gs-active-arg,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2 .gs-active-arg{color:#fff;background-color:#094771}.gs-editor-portal[data-mode=dark] .gs-fn-guide2-arg-type,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2-arg-type,.gs-editor[data-mode=dark] .gs-fn-guide2-arg-type,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2-arg-type{background:#094771;color:#4fc1ff}.gs-editor-portal[data-mode=dark] .gs-fn-guide2-desc,.gs-editor-portal[data-mode=inherit-dark] .gs-fn-guide2-desc,.gs-editor[data-mode=dark] .gs-fn-guide2-desc,.gs-editor[data-mode=inherit-dark] .gs-fn-guide2-desc{color:#aaa;border-top-color:#333}.gs-fn-guide2{position:fixed;left:0;background:#fff;border:1px solid rgba(0,0,0,.1);box-shadow:0 4px 16px rgba(0,0,0,.12);border-radius:6px;padding:12px 16px;width:280px;z-index:1000;cursor:default;white-space:normal;color:#333;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;transition:opacity .1s ease-in-out}.gs-fn-guide2.gs-fn-guide2-hidden{opacity:0!important;pointer-events:none!important}.gs-fn-guide2-name{font-family:monospace;font-weight:700;font-size:13px;color:#1a1a1a;background:#f5f5f5;padding:6px 8px;border-radius:4px;border:1px solid #eee;display:flex;align-items:center;gap:6px;flex-wrap:wrap;width:100%;box-sizing:border-box;margin-bottom:8px}.gs-fn-guide2-args-inline{font-size:13px;font-family:monospace;line-height:1.5;margin-bottom:8px;color:#666}.gs-fn-guide2-args-inline span{transition:all .2s ease-in-out}.gs-fn-guide2 .gs-active-arg{font-weight:700;color:var(--gs-accent,#2563eb);background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);padding:2px 4px;margin:0 -4px;border-radius:4px}.gs-fn-guide2-arg-type{color:var(--gs-accent,#2563eb);padding:0 4px;background:color-mix(in srgb,var(--gs-accent,#2563eb) 12%,transparent);border-radius:3px;font-size:11px;margin:0 4px}.gs-fn-guide2-desc{font-size:12px;color:#555;line-height:1.4;border-top:1px solid #eee;padding-top:8px;margin-top:4px}.gs-fn-guide2-desc p{margin:0}.gs-fn-guide2-desc-more{font-style:italic;color:#888;margin-top:4px!important;font-size:11px}.gs-adjuster{padding:0}.gs-table{margin:0}.gs-tabular{overflow:auto;overflow-anchor:none;display:flex;box-sizing:border-box;position:relative}.gs-root1[data-matrix-align=both] .gs-tabular,.gs-root1[data-matrix-align=horizontal] .gs-tabular{justify-content:safe center}.gs-root1[data-matrix-align=both] .gs-tabular,.gs-root1[data-matrix-align=vertical] .gs-tabular{align-items:safe center}.gs-tabular-inner{flex:0 0 auto;position:relative;overflow:hidden;overflow:clip;box-sizing:border-box;border-right:solid var(--gs-mx-br,1px) var(--gs-border,#e3e6ea);border-bottom:solid var(--gs-mx-bb,1px) var(--gs-border,#e3e6ea)}.gs-tabular-inner>table{table-layout:fixed;border-collapse:collapse;border-spacing:0}.gs-ghost-cell{padding:0;box-sizing:border-box;border:dashed 1px var(--gs-border,#e3e6ea);background-color:var(--gs-surface,#fff);opacity:.5;cursor:crosshair}.gs-ghost-th{opacity:.5}.gs-ghost-th-top{top:0}.gs-ghost-th-left{left:0}.gs-main[data-overflow-x=true] .gs-tabular-inner{border-right-width:0}.gs-main[data-overflow-y=true] .gs-tabular-inner{border-bottom-width:0}.gs-main::after{content:'';position:absolute;inset:0;pointer-events:none;z-index:3;border:0 solid var(--gs-border,#e3e6ea)}.gs-main[data-overflow-x=true]::after{border-right-width:var(--gs-mx-br,1px)}.gs-main[data-overflow-y=true]::after{border-bottom-width:var(--gs-mx-bb,1px)}.gs-th{z-index:2;padding:0;position:sticky;font-size:13px;font-weight:400;box-sizing:border-box;vertical-align:top}.gs-th .gs-resizer{position:absolute;border-color:transparent;box-sizing:border-box;z-index:2}.gs-th .gs-resizer:hover{background-color:var(--gs-accent,#2563eb)}.gs-th .gs-resizer.gs-protected{display:none}.gs-th-inner{height:100%;box-sizing:border-box;vertical-align:middle;overflow:hidden;display:flex;align-items:center;justify-content:center}.gs-th-inner-wrap{height:100%;box-sizing:border-box;background-color:transparent}.gs-th-top{top:0;overflow:hidden}.gs-th-top .gs-resizer{top:0;right:0;width:3px;cursor:e-resize}.gs-th-top .gs-resizer.gs-dragging{border-right-style:dotted;height:1000000px!important;cursor:e-resize}.gs-th-left{left:0;overflow:hidden;min-width:30px;border-top:solid 1px var(--gs-border,#e3e6ea)}.gs-th-left .gs-resizer{left:0;bottom:0;height:3px;cursor:n-resize}.gs-th-left .gs-resizer.gs-dragging{border-bottom-style:dotted;width:1000000px!important;cursor:n-resize}.gs-th-top.gs-th-left{top:0;left:0;z-index:3;border:none!important}.gs-th-left.gs-filter-fixed .gs-th-inner::before{content:'‹\00a0'}.gs-th-left.gs-sort-fixed .gs-th-inner::after{content:'\00a0›'}.gs-col-addr{position:absolute;top:2px;right:4px;font-size:9px;opacity:.5;line-height:1;letter-spacing:.3px;pointer-events:none}.gs-search-bar{width:100%;display:flex;align-items:center;padding:3px 0;border-top:solid 1px rgba(128,128,128,.3);border-left:solid 1px rgba(128,128,128,.3);border-right:solid 1px rgba(128,128,128,.3);border-bottom:solid 1px rgba(128,128,128,.3);box-sizing:border-box;background-color:rgba(200,50,0,.2)}.gs-search-bar.gs-search-found{background-color:rgba(0,200,100,.2)}.gs-search-bar .gs-search-bar-inner{border-left:solid 1px rgba(128,128,128,.5)}.gs-search-bar .gs-search-bar-icon{border-left:solid 1px rgba(128,128,128,.3);display:flex;align-items:center;justify-content:center;width:30px;flex-shrink:0}.gs-search-bar .gs-search-input-wrapper{flex-grow:1;position:relative;display:flex;align-items:center;height:100%}.gs-search-bar .gs-search-input-ghost{position:absolute;left:2px;right:2px;top:0;bottom:0;pointer-events:none;font-size:12px;font-family:monospace,Arial;line-height:24px;letter-spacing:1px;white-space:pre-wrap;word-break:break-all;color:transparent;overflow:hidden}.gs-search-bar .gs-search-input-ghost .gs-search-ghost-hint{color:#aaa}.gs-search-bar textarea{background-color:transparent;border:none;padding:0 2px;box-sizing:border-box;outline:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;font-size:12px;font-family:monospace,Arial;height:24px;line-height:24px;min-height:24px;letter-spacing:1px;caret-color:rgba(128,128,128);white-space:pre-wrap;word-break:break-all;flex-grow:1;width:100%;resize:none}.gs-search-progress{color:#999;font-size:13px;width:60px;flex-shrink:0;white-space:nowrap;text-align:center}.gs-search-close{cursor:pointer;display:flex;align-items:center;justify-content:center;width:24px;flex-shrink:0}.gs-search-buttons{display:flex;align-items:center;white-space:nowrap;flex-shrink:0}.gs-search-button{display:inline-flex;cursor:pointer;margin:0 2px}.gs-search-button span{display:inline-block;font-size:11px;padding:3px 5px;background-color:rgba(128,128,128,.1);border:1px solid rgba(128,128,128,.3);border-radius:3px;transition:all .15s ease;line-height:1}.gs-search-button span:hover{background-color:rgba(128,128,128,.2)}.gs-search-button span.gs-search-button-on{color:var(--gs-accent,#2563eb);background-color:color-mix(in srgb,var(--gs-accent,#2563eb) 22%,transparent);border-color:var(--gs-accent,#2563eb)}.gs-search-range span{white-space:nowrap;font-family:monospace}@keyframes spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}.gs-loading-overlay{position:absolute;top:0;left:0;right:0;bottom:0;background:color-mix(in srgb,var(--gs-surface,#fff) 70%,transparent);display:flex;align-items:center;justify-content:center;z-index:100;pointer-events:all}.gs-loading-spinner{width:32px;height:32px;border:3px solid color-mix(in srgb,var(--gs-fg,#1f2328) 12%,transparent);border-top-color:var(--gs-accent,#2563eb);border-radius:50%;animation:spin .8s linear infinite}.gs-progress-overlay{position:absolute;top:0;left:0;right:0;bottom:0;z-index:100;pointer-events:all;display:flex;align-items:center;justify-content:center}.gs-progress-box{min-width:240px;padding:16px 18px;border-radius:8px;background:var(--gs-editor-surface,#fff);border:1px solid var(--gs-border,#e3e6ea);box-shadow:0 6px 24px rgba(0,0,0,.28);display:flex;flex-direction:column;gap:10px}.gs-progress-head{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--gs-fg,#1f2328)}.gs-progress-head .gs-loading-spinner{width:15px;height:15px;border-width:2px}.gs-progress-track{height:6px;border-radius:3px;overflow:hidden;background:color-mix(in srgb,var(--gs-fg,#1f2328) 12%,transparent)}.gs-progress-fill{height:100%;border-radius:3px;background:var(--gs-accent,#2563eb);transition:width .1s linear}@keyframes gs-pending-slide{0%{left:-40%}100%{left:100%}}@keyframes gs-pending-pulse{0%{left:0;width:0}50%{left:0;width:100%}100%{left:100%;width:0}}@keyframes gs-flash{0%{opacity:0}20%{opacity:1}100%{opacity:0}}.gs-flash-overlay{position:absolute;inset:0;pointer-events:none;z-index:9999;background:color-mix(in srgb,var(--gs-accent,#2563eb) 15%,transparent);opacity:0}.gs-flash-overlay--active{animation:gs-flash .6s ease-out forwards} \ No newline at end of file diff --git a/packages/web/src/styles/tabular.less b/packages/web/src/styles/tabular.less index 8d0ec320..f5685e91 100644 --- a/packages/web/src/styles/tabular.less +++ b/packages/web/src/styles/tabular.less @@ -48,39 +48,24 @@ } } -// autoExpand ghost rows/columns: the not-yet-existing cells drawn OUTSIDE the grid (portaled to -// , positioned fixed past the last row/column) while an autofill is dragged on an -// auto-expanding sheet, so the drag can reach them. Theme tokens are copied onto the layer. -.gs-ghost-layer { - font-size: 13px; - .gs-ghost-panel { - position: fixed; - overflow: hidden; - z-index: 1000; - cursor: crosshair; - } - .gs-ghost-cell, - .gs-ghost-th { - position: absolute; - box-sizing: border-box; - } - .gs-ghost-cell { - border: dashed 1px var(--gs-border, #e3e6ea); - background-color: color-mix(in srgb, var(--gs-surface, #ffffff) 70%, transparent); - &.gs-ghost-target { - background-color: color-mix(in srgb, var(--gs-accent, #2563eb) 12%, var(--gs-surface, #ffffff)); - border-color: color-mix(in srgb, var(--gs-accent, #2563eb) 45%, transparent); - } - } - .gs-ghost-th { - display: flex; - align-items: center; - justify-content: center; - background-color: var(--gs-header-bg, #f6f7f9); - color: var(--gs-header-fg, #555); - border: dashed 1px var(--gs-border, #e3e6ea); - opacity: 0.75; - } +// autoExpand ghost rows/columns: the not-yet-existing cells past the last row/column, rendered +// only while an autofill is dragged on an auto-expanding sheet so the drag can reach them. +.gs-ghost-cell { + padding: 0; + box-sizing: border-box; + border: dashed 1px var(--gs-border, #e3e6ea); + background-color: var(--gs-surface, #ffffff); + opacity: 0.5; + cursor: crosshair; +} +.gs-ghost-th { + opacity: 0.5; +} +.gs-ghost-th-top { + top: 0; +} +.gs-ghost-th-left { + left: 0; } // When an axis overflows, the hugging inner border would scroll out of view, so move that