html, body { height: 100%; margin: 0; font-family: 'Segoe UI', Roboto, sans-serif; font-size: 13px; color: #3D454E; }

.ws-app { display: flex; flex-direction: column; height: 100vh; }
/* the reusable DocumentViewer control fills whatever the host gives it */
/* color is explicit, not inherited: the Casepoint/Custom and Relativity themes set .k-window { color: white !important },
   so inside a Telerik window (Redacted / Duplicate Sheet Preview) the formula bar's name box and value inherited white
   text on their white background and looked empty until the text was selected. */
.ws-viewer { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; background: #fff; position: relative; color: #3D454E; }
.ws-viewerbar { display: flex; align-items: center; gap: 8px; padding: 4px 8px; background: #E2EBF3; border-bottom: 1px solid #ACBFD6; }

.ws-openbar { display: flex; align-items: center; gap: 8px; padding: 8px; background: #E2EBF3; border-bottom: 1px solid #ACBFD6; }
.ws-label { font-weight: 600; }
.ws-path { flex: 1 1 auto; min-width: 160px; height: 26px; padding: 0 8px; border: 1px solid #ACBFD6; border-radius: 3px; font-size: 13px; }
.ws-sel { height: 26px; max-width: 240px; border: 1px solid #ACBFD6; border-radius: 3px; font-size: 12px; background: #fff; }
.ws-note { color: #B23B3B; font-size: 12px; }

/* custom colour combo: a swatch box before each colour name (native <option> can't render one) */
.ws-colorcombo { position: relative; }
.ws-colorcombo-btn { display: flex; align-items: center; gap: 6px; height: 26px; min-width: 150px; padding: 0 8px; border: 1px solid #ACBFD6; border-radius: 3px; background: #fff; cursor: pointer; font-size: 12px; color: #3D454E; }
.ws-colorcombo-name { flex: 1 1 auto; text-align: left; }
.ws-colorcombo-caret { font-size: 10px; color: #6b7480; }
.ws-colorcombo-list { position: absolute; top: 28px; left: 0; min-width: 100%; background: #fff; border: 1px solid #ACBFD6; border-radius: 3px; box-shadow: 0 2px 8px rgba(0,0,0,.25); z-index: 1500; padding: 2px; }
.ws-colorcombo-item { display: flex; align-items: center; gap: 6px; padding: 4px 8px; cursor: pointer; border-radius: 2px; white-space: nowrap; }
.ws-colorcombo-item:hover { background: #F3F8FB; }
.ws-colorcombo-item.sel { background: #d6e6fb; }
.ws-swatch { width: 13px; height: 13px; flex: none; border: 1px solid #6b7480; border-radius: 2px; box-sizing: border-box; }
.ws-colorcombo-backdrop { position: fixed; inset: 0; z-index: 1400; }

.ws-btn { height: 26px; padding: 0 12px; border: 1px solid #ACBFD6; background: #fff; color: #3D454E; border-radius: 3px; cursor: pointer; font-size: 12px; }
.ws-btn:hover { background: #F3F8FB; }
.ws-btn.active { background: #d6e6fb; border-color: #0075E0; color: #0670C1; }   /* toggled-on button (e.g. Display in B&W) */
.ws-primary { background: #0075E0; color: #fff; border-color: #0075E0; }
.ws-primary:hover { background: #0670C1; }
.ws-btn:disabled { opacity: .6; cursor: default; }

/* ── Sheet tabs: the classic Excel / WPF-viewer strip ───────────────────────────────────────────────────────
   Compact height, first/prev/next/last nav block on the left, and parallelogram tabs whose slanted edges read
   as the "/" separators between sheet names. The strip itself scrolls but hides its scrollbar — the arrows are
   the scroll affordance, exactly as in the WPF viewer (the old flat strip exposed a full-width native bar).
   The skew lives on a ::before pseudo-element so only the tab SHAPE leans; the label stays upright. */
.ws-tabs { display: flex; align-items: stretch; background: #EDF0F3; border-bottom: 1px solid #ACBFD6; height: 23px; overflow: hidden; }
.ws-tabs-bottom { flex: 0 0 auto; border-bottom: none; border-top: 1px solid #ACBFD6; }

.ws-tabnav { display: flex; align-items: center; flex: 0 0 auto; padding: 0 2px; border-right: 1px solid #ACBFD6; }
.ws-tabnav-btn { width: 17px; height: 21px; display: flex; align-items: center; justify-content: center;
    padding: 0; border: none; background: transparent; color: #3D454E; cursor: pointer; }
.ws-tabnav-btn:hover:not(:disabled) { background: rgba(6,112,193,.16); }
.ws-tabnav-btn:disabled { color: #B6BCC3; cursor: default; }
.ws-tabnav-btn svg { width: 9px; height: 9px; fill: currentColor; display: block; }

.ws-tabstrip { display: flex; align-items: stretch; flex: 1 1 auto; min-width: 0; padding-left: 6px;
    overflow-x: auto; overflow-y: hidden; scroll-behavior: smooth;
    scrollbar-width: none; -ms-overflow-style: none; }              /* Firefox / old Edge */
.ws-tabstrip::-webkit-scrollbar { height: 0; width: 0; display: none; }   /* Chromium / WebKit */

.ws-tab { position: relative; flex: 0 0 auto; display: flex; align-items: center; padding: 0 15px;
    font-size: 12px; color: #3D454E; cursor: pointer; white-space: nowrap; user-select: none; }
.ws-tab::before { content: ''; position: absolute; left: 0; right: 0; top: 0; bottom: 0;
    transform: skewX(-20deg); background: linear-gradient(#FDFDFE, #DFE4E9); border-right: 1px solid #ACBFD6; }
/* The shape is an absolutely-positioned pseudo, so it paints ABOVE the parent's in-flow text. Wrapping the
   label in its own positioned span puts it later in paint order and keeps it on top — z-index:-1 would not
   work here, because .ws-tab establishes no stacking context and the pseudo would sink behind .ws-tabs. */
.ws-tablabel { position: relative; }
.ws-tab:hover::before { background: linear-gradient(#FFF, #E4EDF6); }
/* selected: flat white with a hairline frame so it reads as raised. Open at the TOP — this strip sits BELOW the
   grid, so the selected tab hangs from the sheet it belongs to (the .ws-tabs-bottom border-top is that seam). */
.ws-tab.active { font-weight: 600; color: #1B1B1B; }
.ws-tab.active::before { background: #fff; border: 1px solid #ACBFD6; border-top: none; }
.ws-tab.hidden { color: #ADB5BD; font-style: italic; }

.ws-formula { display: flex; align-items: center; gap: 6px; height: 28px; padding: 0 6px; background: #F3F8FB; border-bottom: 1px solid #ACBFD6; }
.ws-namebox { min-width: 70px; height: 20px; line-height: 20px; padding: 0 6px; background: #fff; border: 1px solid #ACBFD6; text-align: center; font-size: 12px; }
.ws-fx { font-style: italic; color: #8C93A6; }
.ws-content { flex: 1 1 auto; padding: 0 6px; background: #fff; border: 1px solid #ACBFD6; height: 20px; line-height: 20px; overflow: hidden; white-space: nowrap; font-size: 12px; }

.ws-redbar { display: flex; align-items: center; gap: 8px; height: 30px; padding: 0 8px; background: #F3F8FB; border-bottom: 1px solid #ACBFD6; }
.ws-redcount { font-size: 12px; margin-right: 6px; }
.ws-hint { color: #8C93A6; font-size: 11px; margin-left: 8px; }
.ws-bllabel { color: #3D454E; font-size: 12px; white-space: nowrap; }
.ws-blur { width: 110px; vertical-align: middle; cursor: pointer; }
.ws-blurval { color: #8C93A6; font-size: 11px; min-width: 22px; }
.ws-loadmsg { position: absolute; top: 8px; left: 50%; transform: translateX(-50%); z-index: 60;
    background: rgba(255,255,255,0.96); border: 1px solid #ACBFD6; border-radius: 4px; padding: 5px 14px;
    font-size: 12px; font-weight: 600; color: #0670C1; box-shadow: 0 1px 4px rgba(0,0,0,0.15); pointer-events: none; }

.ws-scroll { position: relative; flex: 1 1 auto; min-height: 0; overflow: auto; background: #fff; scrollbar-gutter: stable; }
.ws-sizer { position: relative; }
.ws-canvas { position: sticky; top: 0; left: 0; display: block; }

.ws-empty { padding: 40px; text-align: center; color: #8C93A6; }

/* worksheet embeds (images / charts / text-boxes) + comment tooltip */
/* Excel-style cell note. white-space:pre-wrap keeps authored newlines but only ever breaks at whitespace, so a
   long unbroken run (URL, path, id) used to push the content past max-width and overflow:auto turned that into a
   HORIZONTAL scrollbar - the comment was cut off and the vertical thumb sat off to the right, reachable only by
   scrolling sideways first. overflow-wrap:anywhere lets those runs break, so nothing is ever wider than the box
   and it simply grows downward. overflow-x:hidden is the backstop; max-height caps the growth so a very long
   comment scrolls vertically instead of running off the screen (the box is absolutely positioned at its cell, so
   it cannot grow past the viewport and stay reachable). */
.ws-comment-box { position: absolute; max-width: 340px; min-width: 60px; min-height: 20px; max-height: 50vh; background: #ffffe1; border: 1px solid #a0a0a0; padding: 4px 8px; font-size: 12px; color: #000; box-shadow: 2px 2px 5px rgba(0,0,0,.35); z-index: 1000; white-space: pre-wrap; overflow-wrap: anywhere; pointer-events: auto; cursor: move; user-select: none; resize: both; overflow-x: hidden; overflow-y: auto; }
.ws-embed-text { box-sizing: border-box; padding: 2px 4px; white-space: pre-wrap; word-wrap: break-word; overflow: hidden; }
.ws-embed-drag { pointer-events: auto; cursor: move; }   /* body-drag MOVES the object (Excel-style) */
.ws-embed-drag.drawing { cursor: crosshair; outline: 2px dashed #0075E0; outline-offset: 0; }   /* partial-redaction edit mode: dashed border + draw cursor */
.ws-embed-handle { position: absolute; width: 8px; height: 8px; background: #fff; border: 1px solid #0075E0; pointer-events: auto; z-index: 4; box-sizing: border-box; }
.ws-embed-red { position: absolute; background: rgba(0,0,0,0.40); border: 1px solid rgba(0,0,0,0.70); box-sizing: border-box; pointer-events: none; z-index: 2; }
/* committed partial-redaction sub-box on an embed + its edit affordances */
.ws-part-red { position: absolute; background: rgba(0,0,0,0.40); border: 1px solid rgba(0,0,0,0.70); box-sizing: border-box; pointer-events: auto; cursor: move; z-index: 3; }
.ws-part-red.sel { border: 1px solid #0075E0; }
.ws-part-handle { position: absolute; width: 8px; height: 8px; background: #fff; border: 1px solid #0075E0; box-sizing: border-box; pointer-events: auto; z-index: 5; }
.ws-part-del { position: absolute; width: 16px; height: 16px; line-height: 14px; text-align: center; font-size: 11px; color: #fff; background: #c0392b; border: 1px solid #fff; border-radius: 3px; cursor: pointer; pointer-events: auto; z-index: 6; box-sizing: border-box; }
/* selection popup (two buttons) at the selected object's corner: [partial-redaction toggle] + [full-redaction] */
.ws-embed-pop { position: absolute; display: flex; gap: 2px; padding: 2px; background: #fff; border: 1px solid #0075E0; border-radius: 4px; box-shadow: 0 1px 4px rgba(0,0,0,.4); pointer-events: auto; z-index: 7; box-sizing: border-box; }
.ws-pop-btn { width: 20px; height: 18px; box-sizing: border-box; border: 1px solid transparent; border-radius: 3px; cursor: pointer; display: flex; align-items: center; justify-content: center; }
.ws-pop-btn:hover { background: #F3F8FB; }
.ws-pop-btn.active { background: #d6e6fb; border-color: #0075E0; box-shadow: inset 0 1px 2px rgba(0,0,0,.25); }   /* pressed (mode on) */
.ws-marquee { position: fixed; background: rgba(0,117,224,0.12); border: 1px solid #0075E0; box-sizing: border-box; pointer-events: none; z-index: 3000; }
/* AutoFilter dropdown popup (value checklist + colour swatches + search; NO sort) */
.ws-filter-popup { position: fixed; z-index: 4000; min-width: 220px; max-width: 320px; background: #fff; border: 1px solid #ACBFD6; border-radius: 4px; box-shadow: 0 4px 16px rgba(0,0,0,.28); padding: 8px; font-size: 12px; color: #3D454E; box-sizing: border-box; }
.ws-flt-search { width: 100%; height: 24px; box-sizing: border-box; border: 1px solid #ACBFD6; border-radius: 3px; padding: 0 6px; font-size: 12px; margin-bottom: 6px; }
.ws-flt-section { font-weight: 600; margin: 4px 0 3px; }
.ws-flt-swatches { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 6px; }
.ws-flt-swatch { width: 22px; height: 16px; border: 1px solid #9aa3ae; border-radius: 2px; cursor: pointer; box-sizing: border-box; }
.ws-flt-swatch.sel { border: 2px solid #0075E0; }
.ws-flt-list { max-height: 220px; overflow: auto; border: 1px solid #E2EBF3; border-radius: 3px; padding: 2px 4px; }
.ws-flt-item { display: flex; align-items: center; gap: 4px; padding: 2px 0; cursor: pointer; white-space: nowrap; }
.ws-flt-item:hover { background: #F3F8FB; }
.ws-flt-more { color: #9aa3ae; font-size: 11px; padding: 2px 0; }
.ws-flt-foot { display: flex; gap: 6px; margin-top: 8px; justify-content: flex-end; }
.ws-filter-popup .ws-btn { height: 24px; padding: 0 10px; }
/* character-range text redaction highlight (text-box / comment inline + the Redact-Text dialog) */
.ws-text-red { background: rgba(0,0,0,0.55); border-radius: 1px; }
.ws-rt-text { white-space: pre-wrap; word-wrap: break-word; user-select: text; border: 1px solid #ACBFD6; border-radius: 3px; padding: 8px; max-height: 320px; overflow: auto; font-size: 13px; line-height: 1.5; background: #fff; }
/* A FULLY redacted comment must not become readable by scrolling. The ::after overlay is absolutely positioned
   against the box's padding box, so it covers only what is visible and scrolls away with the content - give the
   box a max-height and a scrollbar and the text below the fold would come out from under it. A whole-comment
   redaction has nothing to read, so the box does not scroll at all: overflow:hidden clips instead, and the
   overlay covers everything that can be seen. (Partial, character-range redactions are unaffected - those are
   inline spans inside the text from redactedHtml(), so they scroll WITH the words they cover and stay correct.) */
.ws-comment-box.redacted { overflow: hidden; }
.ws-comment-box.redacted::after { content: ''; position: absolute; inset: 0; background: var(--ws-red, rgba(0,0,0,0.40)); border: 1px solid rgba(0,0,0,0.70); box-sizing: border-box; pointer-events: none; }
/* position the OIT vector embed structure inside the worksheet embed layer (charts/drawings/text-boxes) */
.ws-embeds .oit-sheet-embedpane, .ws-embeds .oit-sheet-embedlist, .ws-embeds .oit-svg-embed, .ws-embeds .oit-image-embed { position: absolute; }
.ws-embeds .oit-svg { position: relative; }
.ws-embeds .oit-svg svg, .ws-embeds .oit-svg-embed svg { position: absolute; left: 0; top: 0; }
.ws-embeds .oit-svg-layer { pointer-events: none; }
.ws-embeds .oit-svg-text { position: absolute; left: 0; top: 0; white-space: pre; }
.ws-embeds .oit-svg-text div { position: absolute; }

/* document viewer chrome (flow / paginated) */
.doc-wrap { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
.doc-toolbar { display: flex; align-items: center; gap: 8px; height: 30px; padding: 0 8px; background: #F3F8FB; border-bottom: 1px solid #ACBFD6; flex: 0 0 auto; }
.redact-box { position: absolute; background: rgba(0,0,0,0.40); border: 1px solid rgba(0,0,0,0.70); box-sizing: border-box; }
.ws-sep { width: 1px; height: 18px; background: #ACBFD6; margin: 0 6px; display: inline-block; }
.find-hit { background: #ffe28a; color: inherit; }
.find-cur { background: #ff9800; color: #000; }

/* flow (html/email) + image documents */
.doc-flow { flex: 1 1 auto; overflow: auto; background: #fff; padding: 16px; }
.doc-html { max-width: 1000px; margin: 0 auto; }
.doc-img { display: block; margin: 0 auto 12px; max-width: 100%; box-shadow: 0 1px 4px rgba(0,0,0,.25); }

/* paginated documents (Word/RTF/text "page", PDF "drawing") */
.doc-pages { flex: 1 1 auto; overflow: auto; background: #e5e7ea; padding: 16px; display: flex; flex-direction: column; align-items: center; gap: 12px; }
.doc-page { background: #fff; box-shadow: 0 1px 5px rgba(0,0,0,.3); position: relative; overflow: hidden; flex: 0 0 auto; }
/* Our own layout rules for the OIT cache page content (no Oracle assets). The cache HTML positions content
   via these structural class names; these are the functional rules needed to lay it out:
   overlay the SVG layers, and place each absolutely-positioned text run without collapsing whitespace. */
.doc-page div { box-sizing: content-box; }
.doc-page .oit-svg { position: relative; }
.doc-page .oit-svg svg, .doc-page .oit-svg-embed svg { position: absolute; left: 0; top: 0; }
.doc-page .oit-svg-layer { pointer-events: none; }
.doc-page .oit-svg-embed, .doc-page .oit-image-embed { position: absolute; }
.doc-page .oit-svg-text { position: absolute; left: 0; top: 0; margin: 0; white-space: pre; }
.doc-page .oit-svg-text div { position: absolute; }
/* "page" type (Word/RTF/text): the text runs live in .oit-body, absolutely positioned by inline top/left */
.doc-page .oit-body { position: absolute; top: 0; left: 0; width: 100%; }
.doc-page .oit-body div { position: absolute; white-space: pre; }
.doc-page .oit-body div span { vertical-align: top; }

/* streaming text viewer */
.txt-scroll { flex: 1 1 auto; overflow: auto; background: #fff; }
.txt-sizer { position: relative; }
.txt-rows { position: absolute; top: 0; left: 0; right: 0; font-family: Consolas, 'Courier New', monospace; font-size: 13px; }
.txt-line { height: 18px; line-height: 18px; white-space: pre; display: flex; }
.txt-no { flex: 0 0 auto; width: 60px; padding-right: 10px; text-align: right; color: #9aa3ad; user-select: none; background: #f5f6f8; }
.txt-tx { flex: 1 1 auto; padding-left: 8px; }
.txt-hit { background: #fff7cc; }
.txt-rows mark { background: #ffd54a; color: inherit; padding: 0; }
.txt-findbox { height: 22px; border: 1px solid #ACBFD6; border-radius: 3px; padding: 0 6px; font-size: 12px; }
.ws-btn.active { background: #0075E0; color: #fff; border-color: #0075E0; }

/* folder browser modal */
.ws-modal-backdrop { position: fixed; inset: 0; background: rgba(0,0,0,.35); display: flex; align-items: center; justify-content: center; z-index: 10000; }
.ws-modal { width: 560px; max-width: 92vw; max-height: 80vh; background: #fff; border-radius: 6px; box-shadow: 0 8px 30px rgba(0,0,0,.3); display: flex; flex-direction: column; }
.ws-msgbox { width: 400px; }
.ws-msgbox-body { padding: 18px 16px; font-size: 13px; color: #3D454E; line-height: 1.45; }
.ws-modal-head { display: flex; align-items: center; justify-content: space-between; padding: 10px 14px; border-bottom: 1px solid #E1E4E8; font-weight: 600; }
.ws-x { border: none; background: transparent; font-size: 14px; cursor: pointer; color: #6B7480; }
.ws-crumb { display: flex; align-items: center; gap: 6px; padding: 6px 14px; background: #F7FAFC; border-bottom: 1px solid #E1E4E8; }
.ws-crumb-input { flex: 1 1 auto; height: 24px; padding: 0 8px; border: 1px solid #ACBFD6; border-radius: 3px; font-size: 12px; }
.ws-modal-list { flex: 1 1 auto; overflow: auto; padding: 4px 0; }
.ws-row { display: flex; align-items: center; gap: 6px; padding: 5px 14px; cursor: pointer; font-size: 13px; }
.ws-row:hover { background: rgba(6,112,193,.08); }
.ws-row.up { color: #0075E0; }
.ws-row.muted { color: #ADB5BD; cursor: default; }
.ws-row.muted:hover { background: transparent; }
.ws-row.manifest { color: #2E7D32; font-weight: 600; }
.ws-row.file { color: #ADB5BD; cursor: default; }
.ws-row.file:hover { background: transparent; }
.ws-row.err { color: #B23B3B; cursor: default; }
.ws-row.err:hover { background: transparent; }
.ws-ico { width: 16px; text-align: center; }
.ws-modal-foot { display: flex; align-items: center; gap: 8px; padding: 10px 14px; border-top: 1px solid #E1E4E8; }
.ws-ok { color: #2E7D32; font-size: 12px; }
.ws-spacer { flex: 1 1 auto; }

/* ── Find dialog (port of the WPF worksheet Find window) ── */
.ws-findmodal { width: 600px; }
.ws-find-body { display: flex; flex-direction: column; gap: 8px; padding: 12px; min-height: 0; }
.ws-find-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.ws-find-lbl { font-size: 12px; color: #3D454E; }
.ws-find-what { flex: 1 1 auto; min-width: 160px; height: 24px; padding: 0 6px; border: 1px solid #ACBFD6; border-radius: 3px; font-size: 13px; }
.ws-find-preset, .ws-find-within { height: 26px; border: 1px solid #ACBFD6; border-radius: 3px; font-size: 12px; background: #fff; }
.ws-chk { font-size: 12px; color: #3D454E; display: inline-flex; align-items: center; gap: 4px; }
.ws-find-busy { color: #0670C1; font-size: 13px; letter-spacing: 2px; animation: ws-blink 1s steps(1) infinite; }
@keyframes ws-blink { 50% { opacity: .35; } }
/* AutoFilter busy veil: fixed over the grid's scroll area while the filter values load or a filter applies (worksheet.js showBusy). */
.ws-busy { position: fixed; z-index: 3990; display: flex; align-items: center; justify-content: center; background: rgba(255,255,255,.6); color: #0670C1; font-size: 13px; font-weight: 600; letter-spacing: .5px; cursor: progress; }
.ws-find-list { flex: 1 1 auto; min-height: 160px; max-height: 38vh; overflow: auto; border: 1px solid #E1E4E8; border-radius: 4px; }
.ws-find-hdr, .ws-find-item { display: flex; gap: 0; font-size: 12px; }
.ws-find-hdr { position: sticky; top: 0; background: #F3F8FB; border-bottom: 1px solid #E1E4E8; font-weight: 600; color: #3D454E; }
.ws-find-item { border-bottom: 1px solid #F0F2F4; cursor: pointer; }
.ws-find-item:hover { background: #F5F9FC; }
.ws-find-item.sel { background: #D6E9FB; }
.ws-find-c1 { flex: 0 0 120px; padding: 4px 8px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ws-find-c2 { flex: 0 0 120px; padding: 4px 8px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ws-find-c3 { flex: 1 1 auto; padding: 4px 8px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ws-find-foot { display: flex; align-items: center; justify-content: space-between; font-size: 12px; }
.ws-find-status { color: #3D454E; }
.ws-find-elapsed { color: #8C93A6; }
