diff --git a/PlotLine/Controllers/WordCompanionController.cs b/PlotLine/Controllers/WordCompanionController.cs index 2b3a8c6..66edf26 100644 --- a/PlotLine/Controllers/WordCompanionController.cs +++ b/PlotLine/Controllers/WordCompanionController.cs @@ -1,5 +1,8 @@ using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.SignalR; using Microsoft.AspNetCore.Mvc; +using System.Security.Claims; +using PlotLine.Hubs; using PlotLine.Models; using PlotLine.Services; @@ -8,7 +11,9 @@ namespace PlotLine.Controllers; [ApiController] [Authorize] [Route("api/word-companion")] -public sealed class WordCompanionController(IWordCompanionService wordCompanion) : ControllerBase +public sealed class WordCompanionController( + IWordCompanionService wordCompanion, + IHubContext followHub) : ControllerBase { [HttpGet("projects")] public Task GetProjects() => wordCompanion.ListProjectsAsync(); @@ -116,6 +121,27 @@ public sealed class WordCompanionController(IWordCompanionService wordCompanion) return response is null ? BadRequest() : Ok(response); } + [HttpPost("runtime/current-scene")] + public async Task UpdateRuntimeCurrentScene(WordCompanionRuntimeCurrentSceneRequest request) + { + var response = await wordCompanion.ValidateRuntimeCurrentSceneAsync(request); + if (response is null) + { + return BadRequest(); + } + + await BroadcastToCurrentUserAsync("wordCompanionSceneChanged", new + { + response.ProjectId, + response.BookId, + response.ChapterId, + response.SceneId, + response.SceneUrl + }); + + return Ok(response); + } + [HttpGet("runtime/characters")] public async Task GetRuntimeCharacters([FromQuery] int projectId, [FromQuery] Guid documentGuid) { @@ -169,6 +195,29 @@ public sealed class WordCompanionController(IWordCompanionService wordCompanion) public async Task CreateDiscoveredCharacters(WordCompanionCreateDiscoveredCharactersRequest request) { var response = await wordCompanion.CreateDiscoveredCharactersAsync(request); - return response is null ? BadRequest() : Ok(response); + if (response is null) + { + return BadRequest(); + } + + if (response.CreatedCount > 0) + { + await BroadcastToCurrentUserAsync("wordCompanionCharactersCreated", new + { + response.ProjectId, + CharactersUrl = Url.Action("Index", "Characters", new { projectId = response.ProjectId }) ?? $"/Characters?projectId={response.ProjectId}" + }); + } + + return Ok(response); + } + + private async Task BroadcastToCurrentUserAsync(string eventName, object payload) + { + var userId = User.FindFirstValue(ClaimTypes.NameIdentifier); + if (!string.IsNullOrWhiteSpace(userId)) + { + await followHub.Clients.User(userId).SendAsync(eventName, payload); + } } } diff --git a/PlotLine/Data/WordCompanionRepository.cs b/PlotLine/Data/WordCompanionRepository.cs index 8561a3e..d74023a 100644 --- a/PlotLine/Data/WordCompanionRepository.cs +++ b/PlotLine/Data/WordCompanionRepository.cs @@ -20,6 +20,7 @@ public interface IWordCompanionRepository Task UpdateSceneLinksAsync(int sceneId, int userId, WordCompanionUpdateSceneLinksRequest request); Task UpdateWordCountAsync(int sceneId, int userId, int actualWords, DateTime? lastWorkedOn); Task UpdateRuntimeSceneWordCountAsync(int userId, WordCompanionRuntimeSceneWordCountRequest request); + Task ValidateRuntimeCurrentSceneAsync(int userId, WordCompanionRuntimeCurrentSceneRequest request); Task> ListRuntimeCharacterAliasesAsync(int userId, int projectId, Guid documentGuid); Task CreateRuntimeCharacterSuggestionsAsync(int userId, WordCompanionRuntimeCharacterSuggestionsRequest request); Task AnalyseManuscriptAsync(int userId, WordCompanionManuscriptAnalyseRequest request); @@ -255,6 +256,23 @@ public sealed class WordCompanionRepository(ISqlConnectionFactory connectionFact commandType: CommandType.StoredProcedure); } + public async Task ValidateRuntimeCurrentSceneAsync(int userId, WordCompanionRuntimeCurrentSceneRequest request) + { + using var connection = connectionFactory.CreateConnection(); + return await connection.QuerySingleOrDefaultAsync( + "dbo.WordCompanion_Runtime_CurrentScene_Validate", + new + { + UserID = userId, + request.DocumentGuid, + request.ProjectId, + request.BookId, + request.ChapterId, + request.SceneId + }, + commandType: CommandType.StoredProcedure); + } + public async Task> ListRuntimeCharacterAliasesAsync(int userId, int projectId, Guid documentGuid) { using var connection = connectionFactory.CreateConnection(); diff --git a/PlotLine/Hubs/WordCompanionFollowHub.cs b/PlotLine/Hubs/WordCompanionFollowHub.cs new file mode 100644 index 0000000..2b1b662 --- /dev/null +++ b/PlotLine/Hubs/WordCompanionFollowHub.cs @@ -0,0 +1,9 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.SignalR; + +namespace PlotLine.Hubs; + +[Authorize] +public sealed class WordCompanionFollowHub : Hub +{ +} diff --git a/PlotLine/Models/WordCompanionApiModels.cs b/PlotLine/Models/WordCompanionApiModels.cs index e3e63a5..0fb4636 100644 --- a/PlotLine/Models/WordCompanionApiModels.cs +++ b/PlotLine/Models/WordCompanionApiModels.cs @@ -228,6 +228,24 @@ public sealed class WordCompanionRuntimeSceneWordCountRequest public int WordCount { get; set; } } +public sealed class WordCompanionRuntimeCurrentSceneRequest +{ + public Guid DocumentGuid { get; set; } + public int ProjectId { get; set; } + public int BookId { get; set; } + public int ChapterId { get; set; } + public int SceneId { get; set; } +} + +public sealed class WordCompanionRuntimeCurrentSceneResponse +{ + public int ProjectId { get; init; } + public int BookId { get; init; } + public int ChapterId { get; init; } + public int SceneId { get; init; } + public string SceneUrl { get; init; } = string.Empty; +} + public sealed class WordCompanionRuntimeCharacterAliasDto { public int CharacterId { get; init; } diff --git a/PlotLine/Program.cs b/PlotLine/Program.cs index cca90da..7804d24 100644 --- a/PlotLine/Program.cs +++ b/PlotLine/Program.cs @@ -6,6 +6,7 @@ using PlotLine.Services; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.DataProtection; using Microsoft.Extensions.FileProviders; +using PlotLine.Hubs; namespace PlotLine; @@ -23,6 +24,7 @@ public class Program { options.Filters.Add(); }); + builder.Services.AddSignalR(); builder.Services.AddHttpContextAccessor(); builder.Services.AddDistributedMemoryCache(); builder.Services.AddSession(options => @@ -209,6 +211,7 @@ public class Program name: "default", pattern: "{controller=Home}/{action=Index}/{id?}") .WithStaticAssets(); + app.MapHub("/hubs/word-companion-follow"); app.Run(); } diff --git a/PlotLine/Services/WordCompanionService.cs b/PlotLine/Services/WordCompanionService.cs index a05a734..e488d43 100644 --- a/PlotLine/Services/WordCompanionService.cs +++ b/PlotLine/Services/WordCompanionService.cs @@ -20,6 +20,7 @@ public interface IWordCompanionService Task UpdateSceneLinksAsync(int sceneId, WordCompanionUpdateSceneLinksRequest request); Task UpdateWordCountAsync(int sceneId, WordCompanionUpdateWordCountRequest request); Task UpdateRuntimeSceneWordCountAsync(WordCompanionRuntimeSceneWordCountRequest request); + Task ValidateRuntimeCurrentSceneAsync(WordCompanionRuntimeCurrentSceneRequest request); Task ListRuntimeCharacterAliasesAsync(int projectId, Guid documentGuid); Task CreateRuntimeCharacterSuggestionsAsync(WordCompanionRuntimeCharacterSuggestionsRequest request); Task GetRuntimeBookAsync(int bookId, Guid documentGuid); @@ -236,6 +237,17 @@ public sealed class WordCompanionService( : repository.UpdateRuntimeSceneWordCountAsync(RequireUserId(), request); } + public Task ValidateRuntimeCurrentSceneAsync(WordCompanionRuntimeCurrentSceneRequest request) + { + return request.DocumentGuid == Guid.Empty + || request.ProjectId <= 0 + || request.BookId <= 0 + || request.ChapterId <= 0 + || request.SceneId <= 0 + ? Task.FromResult(null) + : repository.ValidateRuntimeCurrentSceneAsync(RequireUserId(), request); + } + public async Task ListRuntimeCharacterAliasesAsync(int projectId, Guid documentGuid) { if (projectId <= 0 || documentGuid == Guid.Empty) diff --git a/PlotLine/Sql/101_Phase16J_WordCompanionFollowCurrentScene.sql b/PlotLine/Sql/101_Phase16J_WordCompanionFollowCurrentScene.sql new file mode 100644 index 0000000..c078590 --- /dev/null +++ b/PlotLine/Sql/101_Phase16J_WordCompanionFollowCurrentScene.sql @@ -0,0 +1,52 @@ +SET ANSI_NULLS ON; +GO +SET QUOTED_IDENTIFIER ON; +GO + +CREATE OR ALTER PROCEDURE dbo.WordCompanion_Runtime_CurrentScene_Validate + @UserID int, + @DocumentGuid uniqueidentifier, + @ProjectID int, + @BookID int, + @ChapterID int, + @SceneID int +AS +BEGIN + SET NOCOUNT ON; + + IF @DocumentGuid IS NULL + OR @DocumentGuid = '00000000-0000-0000-0000-000000000000' + OR @ProjectID <= 0 + OR @BookID <= 0 + OR @ChapterID <= 0 + OR @SceneID <= 0 + RETURN; + + SELECT p.ProjectID AS ProjectId, + b.BookID AS BookId, + c.ChapterID AS ChapterId, + s.SceneID AS SceneId, + CONCAT(N'/Scenes/Details/', s.SceneID) AS SceneUrl + FROM dbo.Projects p + INNER JOIN dbo.ProjectUserAccess pua ON pua.ProjectID = p.ProjectID + INNER JOIN dbo.Books b ON b.ProjectID = p.ProjectID + INNER JOIN dbo.Chapters c ON c.BookID = b.BookID + INNER JOIN dbo.Scenes s ON s.ChapterID = c.ChapterID + INNER JOIN dbo.ManuscriptDocuments md ON md.ProjectID = p.ProjectID + AND md.BookID = b.BookID + WHERE p.ProjectID = @ProjectID + AND b.BookID = @BookID + AND c.ChapterID = @ChapterID + AND s.SceneID = @SceneID + AND md.DocumentGuid = @DocumentGuid + AND md.IsActive = 1 + AND s.IsLinkedToManuscript = 1 + AND s.ManuscriptDocumentID = md.ManuscriptDocumentID + AND p.IsArchived = 0 + AND b.IsArchived = 0 + AND c.IsArchived = 0 + AND s.IsArchived = 0 + AND pua.UserID = @UserID + AND pua.IsActive = 1; +END; +GO diff --git a/PlotLine/Views/Shared/_Layout.cshtml b/PlotLine/Views/Shared/_Layout.cshtml index 2b6f0ea..6e003c5 100644 --- a/PlotLine/Views/Shared/_Layout.cshtml +++ b/PlotLine/Views/Shared/_Layout.cshtml @@ -150,6 +150,9 @@ @if (User.Identity?.IsAuthenticated == true) {
+ Feature Requests @if (featureRequestAttentionCount > 0) @@ -288,6 +291,10 @@ + @if (User.Identity?.IsAuthenticated == true) + { + + } diff --git a/PlotLine/wwwroot/css/site.css b/PlotLine/wwwroot/css/site.css index 2ba7588..1b2f620 100644 --- a/PlotLine/wwwroot/css/site.css +++ b/PlotLine/wwwroot/css/site.css @@ -623,6 +623,21 @@ td.text-end { background: #f3f4f2; } +.word-companion-follow-toggle[aria-pressed="true"] { + border-color: rgba(47, 111, 99, 0.36); + color: var(--plotline-accent-dark); + background: var(--plotline-soft); + font-weight: 700; +} + +.word-companion-follow-toggle[aria-pressed="true"]::after { + content: " On"; +} + +.word-companion-follow-toggle[aria-pressed="false"]::after { + content: " Off"; +} + .order-buttons { display: flex; gap: 6px; diff --git a/PlotLine/wwwroot/css/site.min.css b/PlotLine/wwwroot/css/site.min.css index a5b1d0f..81a6db0 100644 --- a/PlotLine/wwwroot/css/site.min.css +++ b/PlotLine/wwwroot/css/site.min.css @@ -1 +1 @@ -html{font-size:15px;min-height:100%}@media(min-width:768px){html{font-size:16px}}:root{--plotline-ink:#1e252b;--plotline-muted:#66717b;--plotline-paper:#fbfaf7;--plotline-panel:#fff;--plotline-line:#d8ddd8;--plotline-accent:#2f6f63;--plotline-accent-dark:#22534a;--plotline-soft:#eef5f2;--timeline-label-width:180px;--timeline-scene-width:220px;--timeline-grid-gap:10px}body{min-height:100%;margin-bottom:0;color:var(--plotline-ink);background:var(--plotline-paper)}a{color:var(--plotline-accent-dark)}.btn-primary{--bs-btn-bg:var(--plotline-accent);--bs-btn-border-color:var(--plotline-accent);--bs-btn-hover-bg:var(--plotline-accent-dark);--bs-btn-hover-border-color:var(--plotline-accent-dark)}.btn-outline-primary{--bs-btn-color:var(--plotline-accent-dark);--bs-btn-border-color:var(--plotline-accent);--bs-btn-hover-bg:var(--plotline-accent);--bs-btn-hover-border-color:var(--plotline-accent)}.plotline-nav{background:rgba(255,255,255,.94);backdrop-filter:blur(8px)}.plotline-shell{max-width:1480px;padding-left:24px;padding-right:24px}.plotline-shell-wide{max-width:none;padding-left:clamp(18px,2vw,32px);padding-right:clamp(18px,2vw,32px)}.page-heading{display:flex;align-items:flex-start;justify-content:space-between;gap:24px;margin:18px 0 24px}.workspace-heading{display:flex;align-items:flex-end;justify-content:space-between;gap:18px;margin:14px 0 18px}.workspace-heading h1{margin:0;font-size:clamp(1.8rem,3vw,2.7rem);line-height:1.05}.page-heading.compact{max-width:980px}.page-heading h1{margin:0;font-size:clamp(2rem,4vw,3.2rem);line-height:1.05;letter-spacing:0}.eyebrow{margin:0 0 6px;color:var(--plotline-accent-dark);font-size:.78rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase}.lead-text{max-width:760px;margin:10px 0 0;color:var(--plotline-muted);font-size:1.05rem}.button-row{display:flex;flex-wrap:wrap;align-items:center;gap:8px}.button-row form,.compact-buttons form,.asset-card-footer form,td.text-end form,form[data-confirm-message]{display:inline-flex;align-items:center;margin:0}td.text-end{white-space:nowrap}.content-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:16px}.plain-card,.empty-panel,.edit-panel,.list-section{background:var(--plotline-panel);border:1px solid var(--plotline-line);border-radius:8px;padding:20px;box-shadow:0 10px 24px rgba(30,37,43,.04)}.plain-card h2,.empty-panel h2,.list-section h2{margin-top:0;font-size:1.35rem}.plain-card p,.empty-panel p,.muted{color:var(--plotline-muted)}.edit-panel{max-width:980px}.feature-request-admin-page .page-heading.compact,.feature-request-admin-page .edit-panel{max-width:none}.feature-request-admin-table{table-layout:fixed}.feature-request-admin-table th,.feature-request-admin-table td{vertical-align:middle}.feature-request-admin-table__preview{max-width:180px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.feature-request-admin-table__action{width:78px}@media(max-width:1100px){.feature-request-admin-table{table-layout:auto}.feature-request-admin-table__preview{max-width:160px}}.trial-status-panel,.trial-dashboard-banner{border:1px solid var(--plotline-line);border-radius:8px;padding:18px 20px;background:var(--plotline-panel)}.trial-status-panel{display:grid;gap:12px;margin-bottom:18px}.trial-status-panel--signup{grid-template-columns:minmax(0,1fr) auto;align-items:center;max-width:980px}.trial-status-panel h2,.trial-status-panel h3,.trial-dashboard-banner h2{margin:0}.trial-status-panel p,.trial-dashboard-banner p{margin-bottom:0}.trial-status-panel__heading,.trial-dashboard-banner{display:flex;gap:16px;align-items:center;justify-content:space-between}.trial-dashboard-banner{margin-bottom:18px}.trial-dashboard-banner__body{min-width:0}.trial-dashboard-banner__actions{display:flex;flex:0 0 auto;flex-wrap:wrap;gap:8px}.trial-progress{height:10px;overflow:hidden;border-radius:999px;background:rgba(84,68,48,.12)}.trial-progress__bar{height:100%;border-radius:inherit}.trial-status-panel[hidden],.trial-dashboard-banner[hidden]{display:none}.location-page .page-heading.compact,.location-page .edit-panel,.location-page .empty-panel,.location-page .drag-drop-panel{max-width:none}.import-panel,.import-preview-section{max-width:none}.import-json-input{font-family:Consolas,"Liberation Mono",Menlo,monospace;font-size:.88rem;line-height:1.45;min-height:34rem;max-height:64vh;overflow:auto;resize:vertical;white-space:pre}.import-preview-heading,.import-counts{display:flex;align-items:flex-start;gap:12px}.import-preview-heading{justify-content:space-between;margin-bottom:16px}.import-counts{flex-wrap:wrap}.import-counts span{display:inline-flex;align-items:baseline;gap:5px;border:1px solid var(--plotline-line);border-radius:999px;padding:5px 11px;background:var(--plotline-soft);color:var(--plotline-muted);font-weight:700}.import-counts strong{color:var(--plotline-ink)}.import-tree{display:grid;gap:12px}.import-tree-book{border:1px solid var(--plotline-line);border-radius:8px;padding:14px;background:rgba(255,255,255,.54)}.import-tree-book>summary,.import-tree-chapter>summary{display:flex;align-items:center;justify-content:space-between;gap:12px;cursor:pointer}.import-tree-book>summary span,.import-tree-chapter>summary span{color:var(--plotline-muted);font-size:.84rem;font-weight:700;white-space:nowrap}.import-tree-book h3{margin:0 0 10px;font-size:1.08rem}.import-tree-chapter{border-top:1px solid var(--plotline-line);padding:10px 0 0;margin-top:10px}.import-tree-chapter ul{margin:8px 0 0;color:var(--plotline-muted)}.import-scene-meta{display:block;margin-top:2px;color:var(--plotline-muted);font-size:.82rem}.import-mapping-summary{display:grid;gap:6px;border:1px solid rgba(184,118,43,.28);border-radius:8px;padding:10px 12px;margin-bottom:14px;background:rgba(251,236,211,.5);color:var(--plotline-muted);font-size:.9rem}.import-duplicate-confirm{border:1px solid rgba(184,118,43,.34);border-radius:8px;padding:12px 12px 12px 38px;background:rgba(251,236,211,.72)}.import-confirmation,.import-docs details{border:1px solid var(--plotline-line);border-radius:8px;padding:16px;background:rgba(255,255,255,.42)}.import-confirmation h3,.import-doc-grid h3{margin-top:0;font-size:1.05rem}.import-docs summary{cursor:pointer;font-weight:800}.import-doc-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:14px;margin-top:14px}.import-message-list ul{max-height:16rem;overflow:auto}.scene-editor{max-width:1180px}.table{margin-bottom:0}.table th{color:var(--plotline-muted);font-size:.78rem;letter-spacing:.06em;text-transform:uppercase}.narrow{width:90px;white-space:nowrap}.status-pill{display:inline-flex;align-items:center;width:fit-content;border:1px solid #c8d8d2;border-radius:999px;padding:2px 8px;color:var(--plotline-accent-dark);background:var(--plotline-soft);font-size:.78rem;font-weight:700;white-space:nowrap}.dashboard-summary-card{border-color:var(--plotline-line)}.dashboard-summary-body{padding:10px 12px}.dashboard-summary-label{margin-bottom:4px;font-size:.7rem;line-height:1.15}.dashboard-summary-value{display:block;font-size:1.45rem;line-height:1}.dashboard-summary-calm{border-color:rgba(47,111,99,.28);background:rgba(238,245,242,.62)}.dashboard-summary-mild{border-color:rgba(197,139,43,.32);background:rgba(255,248,232,.68)}.dashboard-summary-attention{border-color:rgba(142,80,103,.32);background:rgba(252,241,246,.7)}.dashboard-progress-card{border-color:rgba(47,111,99,.18);background:linear-gradient(180deg,#fff 0%,rgba(238,245,242,.64) 100%)}.dashboard-progress-body{padding:12px 14px}.dashboard-progress-heading{margin-bottom:8px}.dashboard-progress-title{margin:0 0 2px;font-size:1.05rem;line-height:1.2}.dashboard-series-progress{height:7px;background:rgba(47,111,99,.1)}.dashboard-series-progress .progress-bar{background:linear-gradient(90deg,var(--plotline-accent),#6fa99b)}.dashboard-progress-source{border-color:rgba(47,111,99,.2);color:var(--plotline-accent-dark);background:rgba(238,245,242,.9)}.dashboard-book-title-block h3{line-height:1.16}.dashboard-book-title-block a{color:var(--plotline-ink);text-decoration-color:rgba(47,111,99,.35)}.dashboard-book-subtitle{color:var(--plotline-muted);font-size:.95rem;line-height:1.25}.dashboard-status-pill{border-color:var(--dashboard-status-border,#c8d8d2);color:var(--dashboard-status-ink,var(--plotline-accent-dark));background:var(--dashboard-status-bg,var(--plotline-soft))}.dashboard-status-published{--dashboard-status-border:rgba(47,111,99,.32);--dashboard-status-bg:#e7f2ed;--dashboard-status-ink:#22534a}.dashboard-status-drafting{--dashboard-status-border:rgba(184,118,43,.35);--dashboard-status-bg:#fff2dd;--dashboard-status-ink:#7b4b12}.dashboard-status-planning{--dashboard-status-border:rgba(51,117,155,.3);--dashboard-status-bg:#e9f3f8;--dashboard-status-ink:#245b78}.dashboard-status-research,.dashboard-status-outlining{--dashboard-status-border:rgba(103,80,164,.26);--dashboard-status-bg:#f0edf8;--dashboard-status-ink:#51417c}.dashboard-status-revising{--dashboard-status-border:rgba(123,82,148,.3);--dashboard-status-bg:#f4eefa;--dashboard-status-ink:#5f3e73}.dashboard-status-editing{--dashboard-status-border:rgba(68,75,130,.3);--dashboard-status-bg:#eceef8;--dashboard-status-ink:#343b72}.dashboard-status-proofreading{--dashboard-status-border:rgba(43,130,123,.3);--dashboard-status-bg:#e6f5f2;--dashboard-status-ink:#23625d}.dashboard-status-ready{--dashboard-status-border:rgba(185,142,30,.34);--dashboard-status-bg:#fff6d8;--dashboard-status-ink:#765a0f}.dashboard-status-paused{--dashboard-status-border:rgba(102,113,123,.28);--dashboard-status-bg:#f0f2f1;--dashboard-status-ink:#56616b}.dashboard-status-archived{--dashboard-status-border:rgba(139,80,86,.28);--dashboard-status-bg:#f3eded;--dashboard-status-ink:#76474d}.dashboard-attention-soft{border-color:rgba(102,113,123,.24);color:#56616b;background:#f3f4f2}.order-buttons{display:flex;gap:6px}.purpose-list{display:grid;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));gap:8px;max-height:260px;overflow:auto;padding:10px;border:1px solid var(--plotline-line);border-radius:8px;background:#fcfcfb}.purpose-check{display:flex;align-items:center;gap:8px;font-size:.92rem}.timeline-filter{display:flex;align-items:center;gap:8px;min-width:min(420px,100%)}.workspace-layout{display:grid;grid-template-columns:minmax(0,1fr);gap:0;align-items:start;--timeline-inspector-width:min(40vw,560px)}.workspace-layout.inspector-drawer-open{grid-template-columns:minmax(420px,1fr) 10px minmax(420px,var(--timeline-inspector-width));gap:12px}.timeline-workspace{min-width:0;max-width:100%}.timeline-inspector-resizer{position:sticky;top:76px;z-index:25;width:10px;height:calc(100vh - 96px);border-radius:999px;cursor:col-resize;background:linear-gradient(180deg,rgba(47,111,99,.16),rgba(47,111,99,.04))}.timeline-inspector-resizer::before{content:"";display:block;width:2px;height:48px;margin:18px auto;border-radius:999px;background:var(--plotline-accent);opacity:.55}.timeline-inspector-resizer:hover,.timeline-inspector-resizer:focus-visible{background:rgba(47,111,99,.16)}body.timeline-inspector-resizing{cursor:col-resize;user-select:none}.pacing-panel{margin-top:14px;margin-bottom:0;border:1px solid var(--plotline-line);border-radius:8px;padding:14px;background:#fff;box-shadow:0 10px 24px rgba(30,37,43,.04)}.pacing-heading{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;margin-bottom:10px}.pacing-heading h2{margin:0;font-size:1.1rem}.metric-graph-stack{display:grid;gap:10px;max-width:100%;overflow-x:auto;overflow-y:hidden;overscroll-behavior-x:contain;padding-bottom:4px}.metric-graph-row{display:grid;grid-template-columns:150px minmax(260px,1fr);gap:10px;align-items:center;min-width:max(100%,calc(150px + (var(--scene-count,1)*34px)))}.metric-graph-label{color:var(--plotline-muted);font-size:.84rem;font-weight:700}.metric-graph-points{display:grid;grid-template-columns:repeat(var(--scene-count),minmax(28px,1fr));gap:5px;align-items:end;min-height:52px;border-radius:8px;padding:6px;background:linear-gradient(180deg,#f6faf8 0%,#edf4f1 100%);min-width:calc(var(--scene-count)*34px)}.metric-point{display:flex;align-items:flex-end;justify-content:center;height:48px;min-width:28px;color:var(--plotline-accent-dark);text-decoration:none}.metric-point::before{content:"";display:block;width:100%;height:max(8px,var(--metric-height));border-radius:5px 5px 2px 2px;background:linear-gradient(180deg,#6fa99b,var(--plotline-accent-dark));box-shadow:inset 0 1px 0 rgba(255,255,255,.35)}.metric-point span{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0)}.timeline-shell{overflow-x:auto;padding:16px;border:1px solid var(--plotline-line);border-radius:8px;background:linear-gradient(180deg,#fff 0%,#f7faf8 100%)}.workspace-timeline{min-height:420px}.timeline-series-row{display:grid;grid-template-columns:var(--timeline-label-width) max-content;gap:var(--timeline-grid-gap);align-items:stretch;width:max-content;min-width:100%}.timeline-project-title{position:sticky;left:0;z-index:20;display:grid;align-content:start;gap:4px;width:var(--timeline-label-width);min-height:100%;border-radius:8px;padding:12px;color:#fff;background:var(--plotline-accent-dark);font-weight:700;box-shadow:8px 0 18px rgba(30,37,43,.08)}.timeline-project-title span,.timeline-book-title span{color:rgba(255,255,255,.78);font-size:.72rem;letter-spacing:.08em;text-transform:uppercase}.timeline-project-title strong,.timeline-book-title strong{line-height:1.15}.timeline-books{display:flex;gap:var(--timeline-grid-gap);align-items:stretch}.timeline-book{flex:0 0 auto;width:calc((var(--book-scene-count)*var(--timeline-scene-width)) + ((var(--book-scene-count) - 1)*var(--timeline-grid-gap)));min-width:var(--timeline-scene-width)}.timeline-book-title{display:grid;gap:2px;margin-bottom:var(--timeline-grid-gap);border-radius:8px;padding:10px 12px;color:#fff;background:var(--plotline-accent-dark);font-weight:700}.timeline-chapters{display:flex;gap:var(--timeline-grid-gap);align-items:flex-start}.timeline-chapter{flex:0 0 auto;width:calc((var(--chapter-scene-count)*var(--timeline-scene-width)) + ((var(--chapter-scene-count) - 1)*var(--timeline-grid-gap)));min-width:var(--timeline-scene-width);box-sizing:border-box;border-radius:8px;background:rgba(238,245,242,.7);outline:1px solid #d4ded8;outline-offset:0;overflow:visible}.timeline-chapter-title{display:grid;gap:2px;border-bottom:1px solid #d4ded8;padding:10px 12px;color:var(--plotline-accent-dark);font-weight:700}.timeline-chapter-title span{color:var(--plotline-muted);font-size:.76rem;text-transform:uppercase}.timeline-scenes{display:grid;grid-template-columns:repeat(var(--chapter-scene-count),minmax(0,1fr));gap:var(--timeline-grid-gap);width:100%;box-sizing:border-box;min-height:190px;padding:0}.timeline-scene-card,.timeline-empty-scene{display:flex;flex-direction:column;gap:6px;width:100%;min-width:0;box-sizing:border-box;border:1px solid var(--plotline-line);border-radius:8px;padding:12px;background:#fff;color:var(--plotline-ink);text-decoration:none;box-shadow:0 8px 18px rgba(30,37,43,.05)}.timeline-scene-card:hover{border-color:var(--plotline-accent);color:var(--plotline-ink)}.timeline-placeholder-scene,.timeline-placeholder-cell,.metric-point-placeholder{cursor:default;opacity:.72}.timeline-placeholder-scene{align-items:center;justify-content:center;border-style:dashed;color:var(--plotline-muted);background:rgba(255,255,255,.38);font-size:.86rem;font-weight:800;text-align:center}.timeline-placeholder-cell{border-style:dashed;background:repeating-linear-gradient(-45deg,rgba(216,221,216,.18) 0,rgba(216,221,216,.18) 7px,rgba(255,255,255,.18) 7px,rgba(255,255,255,.18) 14px)}.metric-point-placeholder::before{height:4px;background:rgba(102,113,123,.2);box-shadow:none}.timeline-scene-card.selected{border-color:var(--plotline-accent-dark);box-shadow:0 0 0 3px rgba(47,111,99,.16),0 10px 22px rgba(30,37,43,.08)}.scene-badge-row,.purpose-chip-row{display:flex;flex-wrap:wrap;gap:5px;align-items:center}.warning-placeholder{display:inline-flex;width:fit-content;border:1px dashed #d6b25e;border-radius:999px;padding:2px 8px;color:#755715;background:#fff8e8;font-size:.74rem;font-weight:700}.warning-placeholder.active{border-color:rgba(159,69,69,.36);color:#8a3434;background:rgba(255,232,232,.9);gap:5px;font-weight:800}.dependency-placeholder{display:inline-flex;width:fit-content;border:1px solid rgba(47,111,99,.2);border-radius:999px;padding:2px 8px;color:var(--plotline-accent-dark);background:rgba(47,111,99,.08);font-size:.74rem;font-weight:700}.purpose-chip{display:inline-flex;width:fit-content;border-radius:999px;padding:2px 7px;color:#38453e;background:#edf0eb;font-size:.72rem;font-weight:700}.future-lane-placeholder{border-top:1px dashed #cbd8d2;padding:8px 12px;color:var(--plotline-muted);font-size:.78rem;background:rgba(255,255,255,.45)}.metric-timeline-board{display:grid;gap:8px;width:max-content;min-width:100%;margin-top:14px;border-top:1px solid var(--plotline-line);padding-top:14px}.metric-shape-controls{position:sticky;left:0;z-index:6;display:grid;gap:8px;width:calc(var(--timeline-label-width) + (var(--scene-count)*var(--timeline-scene-width)) + (var(--scene-count)*var(--timeline-grid-gap)));min-width:100%;border-radius:8px;padding:10px;background:rgba(255,255,255,.88)}.metric-timeline-row{display:grid;grid-template-columns:var(--timeline-label-width) calc((var(--scene-count)*var(--timeline-scene-width)) + ((var(--scene-count) - 1)*var(--timeline-grid-gap)));gap:var(--timeline-grid-gap);align-items:stretch}.metric-lane-label{position:sticky;left:0;z-index:12;display:grid;align-content:start;gap:4px;min-height:320px;border:1px solid rgba(47,111,99,.18);border-radius:8px;padding:10px;color:var(--plotline-accent-dark);background:#fff;box-shadow:0 6px 14px rgba(30,37,43,.04)}.metric-lane-label span{color:var(--plotline-muted);font-size:.78rem;font-weight:600}.colour-swatch{display:inline-block;width:18px;height:18px;border:1px solid rgba(30,37,43,.18);border-radius:999px;vertical-align:middle}.plot-lane-board{position:relative;display:grid;gap:8px;width:max-content;min-width:100%;margin-top:14px;border-top:1px solid var(--plotline-line);padding-top:14px}.plot-lane-svg-overlay{position:absolute;inset:0 auto auto 0;z-index:4;pointer-events:none;overflow:visible}.plot-lane-svg-health-overlay{z-index:8}.plot-line-svg-path{fill:none;stroke-width:3.5;stroke-linecap:round;opacity:.72}.plot-line-svg-segment-dormant{stroke-dasharray:9 8;opacity:.48}.plot-line-svg-connector{fill:none;stroke-width:3;stroke-linecap:round;opacity:.58}.plot-line-svg-path.plotline-state-resolved,.plot-line-svg-path.plotline-state-questionable{stroke:#8c9491;opacity:.42}.plot-line-svg-path.plotline-state-abandoned{stroke:#9b2f36;opacity:.5}.plot-event-svg-node.plotline-state-resolved,.plot-event-svg-node.plotline-state-questionable{opacity:.88}.plot-event-svg-node.plotline-state-abandoned{opacity:.9}.plot-event-svg-node.plotline-state-abandoned line{stroke:#fff}.plotline-health-marker path,.plotline-health-marker circle{fill:#f4c430;stroke:#8a6712;stroke-width:1.5}.plotline-health-marker{pointer-events:visiblePainted}.plotline-health-marker line,.plotline-health-marker text{stroke:#5e4710;fill:#5e4710;stroke-width:1.6;stroke-linecap:round}.plotline-health-marker text{font-size:11px;font-weight:800;stroke-width:0;pointer-events:none}.plotline-health-count{fill:#fff;stroke:#8a6712;stroke-width:2;paint-order:stroke}.plotline-health-marker-dangling path,.plotline-health-marker-dangling circle{fill:#f8df8f}.plotline-health-marker-abandoned path,.plotline-health-marker-abandoned circle{fill:#d85c63;stroke:#8b1e2d}.plotline-health-marker-abandoned line{stroke:#fff}.plot-event-svg-node circle,.plot-event-svg-node ellipse,.plot-event-svg-node path{stroke:#fff;stroke-width:2}.plot-event-svg-node line,.plot-event-svg-node path[fill="none"]{stroke:#8b1e2d;stroke-width:3.4;stroke-linecap:round;stroke-linejoin:round}.plot-event-svg-node-reveal ellipse{stroke-width:2.4}.plot-event-svg-label{font-size:9.5px;font-weight:900;font-family:system-ui,-apple-system,"Segoe UI",sans-serif;paint-order:stroke;stroke:rgba(30,37,43,.22);stroke-width:.8px;pointer-events:none}.plot-event-svg-node-resolve path[fill="none"]{stroke:#fff}.lane-board-heading,.metric-lane-board-heading,.plot-lane-board-heading{position:sticky;left:0;z-index:6;display:flex;align-items:center;justify-content:space-between;gap:14px;width:calc(var(--timeline-label-width) + (var(--scene-count)*var(--timeline-scene-width)) + (var(--scene-count)*var(--timeline-grid-gap)));min-width:100%;margin-bottom:2px;border-radius:8px;padding:8px 10px;color:var(--plotline-accent-dark);background:rgba(255,255,255,.92);font-weight:700;box-shadow:0 8px 16px rgba(30,37,43,.05)}.lane-board-heading small,.metric-lane-board-heading small,.plot-lane-board-heading small{color:var(--plotline-muted);font-weight:500;white-space:nowrap}.timeline-heading-with-help{display:inline-flex;align-items:center;gap:6px;min-width:0}.plot-lane-row{display:grid;grid-template-columns:var(--timeline-label-width) repeat(var(--scene-count),var(--timeline-scene-width));gap:var(--timeline-grid-gap);align-items:stretch}.plot-lane-label{position:sticky;left:0;z-index:12;display:flex;align-items:center;gap:8px;min-height:46px;border:1px solid color-mix(in srgb,var(--plot-colour),#fff 55%);border-left:5px solid var(--plot-colour);border-radius:8px;padding:8px 10px;background:#fff;color:var(--plotline-ink);text-decoration:none;box-shadow:0 6px 14px rgba(30,37,43,.04)}.plot-lane-label:hover{color:var(--plotline-ink);border-color:var(--plot-colour)}.plot-lane-slots{display:contents}.plot-lane-slot{display:flex;flex-wrap:wrap;align-content:center;align-items:center;justify-content:center;gap:5px;min-height:46px;border:1px dashed #d8ddd8;border-radius:8px;padding:7px;background:rgba(255,255,255,.62)}.thread-marker{position:relative;z-index:5;display:inline-flex;align-items:center;justify-content:center;gap:4px;min-width:34px;height:30px;border:2px solid color-mix(in srgb,var(--plot-colour),#000 20%);border-radius:999px;padding:0 8px;color:var(--plotline-ink);background:color-mix(in srgb,var(--plot-colour),#fff 66%);font-size:.74rem;font-weight:900;text-decoration:none;box-shadow:0 3px 8px rgba(30,37,43,.14)}.plot-lane-board [data-plot-event-node]{opacity:1}.thread-marker:hover,.thread-marker:focus-visible{color:var(--plotline-ink);background:color-mix(in srgb,var(--plot-colour),#fff 48%);outline:3px solid rgba(47,111,99,.22);outline-offset:2px}.thread-marker.resolved{border-color:#5a8c60;background:#e6f4e7;color:#24512b}.thread-marker.contradicted{border-color:#b45c5c;background:#fff0f0;color:#7a2222}.thread-events-section{margin-top:16px}.thread-event-list{display:grid;gap:8px;margin-bottom:12px}.thread-event-item{display:flex;align-items:flex-start;justify-content:space-between;gap:10px;border:1px solid color-mix(in srgb,var(--plot-colour),#fff 55%);border-left:4px solid var(--plot-colour);border-radius:8px;padding:8px;background:#fff}.thread-event-item>div{display:grid;gap:3px}.thread-event-marker{display:inline-flex;align-items:center;justify-content:center;width:fit-content;min-width:24px;height:22px;border-radius:999px;padding:0 7px;background:color-mix(in srgb,var(--plot-colour),#fff 72%);font-size:.72rem;font-weight:800}.thread-event-create{border-top:1px solid var(--plotline-line);padding-top:12px}.asset-lane-board{display:grid;gap:8px;width:max-content;min-width:100%;margin-top:14px;border-top:1px solid var(--plotline-line);padding-top:14px}.asset-lane-row{display:grid;grid-template-columns:var(--timeline-label-width) repeat(var(--scene-count),var(--timeline-scene-width));gap:var(--timeline-grid-gap);align-items:stretch}.asset-lane-label{position:sticky;left:0;z-index:12;display:grid;gap:2px;min-height:46px;border:1px solid #d4d7df;border-left:5px solid #6b5b95;border-radius:8px;padding:8px 10px;background:#fff;color:var(--plotline-ink);text-decoration:none;box-shadow:0 6px 14px rgba(30,37,43,.04)}.asset-lane-label span{color:var(--plotline-muted);font-size:.75rem}.asset-lane-slots{display:contents}.asset-lane-slot{display:flex;flex-wrap:wrap;align-content:flex-start;gap:5px;min-height:46px;border:1px dashed #d8ddd8;border-radius:8px;padding:7px;background:rgba(250,249,255,.72)}.asset-marker,.asset-event-marker{display:inline-flex;align-items:center;justify-content:center;min-width:26px;height:24px;border:1px solid #7f70aa;border-radius:7px;padding:0 7px;color:#33284e;background:#eee9fb;font-size:.72rem;font-weight:800;text-decoration:none}.asset-marker:hover{color:#33284e;background:#dfd6f7}.asset-marker.timeline-marker-story-turn,.character-marker.timeline-marker-story-turn{border-width:2px}.asset-marker.timeline-marker-important,.character-marker.timeline-marker-important{box-shadow:inset 0 -3px 0 rgba(197,139,43,.36)}.asset-marker.timeline-marker-state-change,.character-marker.timeline-marker-state-change{border-style:double}.asset-marker.timeline-marker-transfer{box-shadow:inset 3px 0 0 rgba(47,111,99,.32)}.character-marker.timeline-marker-exit{opacity:.86;border-style:dashed}.asset-marker.timeline-marker-has-warning,.character-marker.timeline-marker-has-warning{box-shadow:0 0 0 2px rgba(179,95,59,.22)}.asset-events-section{margin-top:16px}.asset-event-list,.asset-mini-list{display:grid;gap:8px;margin-bottom:12px}.asset-event-item,.asset-mini-item{display:flex;align-items:flex-start;justify-content:space-between;gap:10px;border:1px solid #ded9ea;border-left:4px solid #6b5b95;border-radius:8px;padding:8px;background:#fff}.asset-event-item>div,.asset-mini-item>div{display:grid;gap:3px}.asset-create-form{border-top:1px solid var(--plotline-line);padding-top:12px}.asset-card-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:12px}.asset-card{display:grid;gap:12px;border:1px solid var(--plotline-line);border-radius:8px;padding:14px;background:#fff;box-shadow:0 8px 18px rgba(30,37,43,.04)}.asset-card h2{margin:0;font-size:1.1rem}.asset-card-footer{display:flex;flex-wrap:wrap;align-items:center;gap:6px}.asset-detail-grid{display:grid;grid-template-columns:minmax(260px,.8fr) minmax(320px,1.2fr);gap:14px}.character-lane-board{display:grid;gap:8px;width:max-content;min-width:100%;margin-top:14px;border-top:1px solid var(--plotline-line);padding-top:14px}.character-lane-row{display:grid;grid-template-columns:var(--timeline-label-width) repeat(var(--scene-count),var(--timeline-scene-width));gap:var(--timeline-grid-gap);align-items:stretch}.character-lane-label{position:sticky;left:0;z-index:12;display:grid;gap:2px;min-height:46px;border:1px solid #d7d4ce;border-left:5px solid #8a6f3d;border-radius:8px;padding:8px 10px;background:#fff;color:var(--plotline-ink);text-decoration:none;box-shadow:0 6px 14px rgba(30,37,43,.04)}.character-lane-label span{color:var(--plotline-muted);font-size:.75rem}.character-lane-slots{display:contents}.character-lane-slot{display:flex;flex-wrap:wrap;align-content:flex-start;gap:5px;min-height:46px;border:1px dashed #d8ddd8;border-radius:8px;padding:7px;background:rgba(255,252,246,.72)}.character-marker{display:inline-flex;align-items:center;justify-content:center;min-width:26px;height:24px;border:1px solid #9a7a3f;border-radius:999px;padding:0 7px;color:#4f3810;background:#fff2d7;font-size:.72rem;font-weight:800;text-decoration:none}.character-card{border-left:4px solid #8a6f3d}.character-section{margin-top:16px}.character-item{border-left-color:#8a6f3d}.character-appearance-card{display:grid;gap:8px;border:1px solid #d7d4ce;border-left:4px solid #8a6f3d;border-radius:8px;padding:10px;background:#fff}.character-appearance-summary{display:flex;align-items:flex-start;justify-content:space-between;gap:12px}.character-appearance-summary>div:first-child{display:grid;gap:3px}.character-appearance-actions{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:6px}.character-appearance-edit .asset-create-form{margin-top:8px;border-top:1px solid var(--plotline-line)}.word-companion-suggestion-panel{display:grid;gap:8px;margin-bottom:12px;border:1px solid rgba(138,111,61,.24);border-radius:8px;padding:10px;background:rgba(255,248,232,.72)}.word-companion-suggestion-list{display:grid;gap:8px}.word-companion-suggestion-item{display:flex;align-items:flex-start;justify-content:space-between;gap:10px;border:1px solid #ded9ea;border-left:4px solid #8a6f3d;border-radius:8px;padding:8px;background:#fff}.word-companion-suggestion-item>div:first-child{display:grid;gap:3px}.word-companion-suggestion-pill{margin-left:6px}.form-helper-message{margin:0 0 8px;font-size:.86rem;font-weight:700}.scene-number,.time-label{color:var(--plotline-muted);font-size:.82rem}.location-pill,.location-badge{display:inline-flex;align-items:center;width:fit-content;border:1px solid rgba(47,111,99,.18);border-radius:999px;padding:2px 7px;color:var(--plotline-accent-dark);background:rgba(47,111,99,.08);font-size:.74rem;font-weight:700}.scene-summary{display:-webkit-box;overflow:hidden;color:var(--plotline-muted);font-size:.88rem;-webkit-box-orient:vertical;-webkit-line-clamp:4}.timeline-empty-scene{justify-content:center;color:var(--plotline-muted);background:rgba(255,255,255,.58)}.form-control:focus,.form-select:focus,.form-check-input:focus{border-color:var(--plotline-accent);box-shadow:0 0 0 .2rem rgba(47,111,99,.16)}.scene-inspector-panel{position:sticky;top:76px;display:flex;flex-direction:column;max-height:calc(100vh - 96px);min-width:0;overflow:hidden;border:1px solid var(--plotline-line);border-radius:8px;background:#fff;box-shadow:0 14px 32px rgba(30,37,43,.08)}.inspector-header{position:sticky;top:0;z-index:5;display:flex;align-items:flex-start;justify-content:space-between;gap:12px;border-bottom:1px solid var(--plotline-line);padding:16px;background:#fff}.scene-inspector-body{flex:1 1 auto;min-height:0;overflow:auto;padding:16px}.inspector-header h2{margin:0;font-size:1.25rem}.scene-inspector-form{display:grid;gap:14px}.inspector-section{border-top:1px solid var(--plotline-line);padding-top:12px}.inspector-section:first-of-type{border-top:0;padding-top:0}.inspector-section h3{margin:0 0 10px;font-size:.95rem;color:var(--plotline-accent-dark)}.location-helper{border:1px solid rgba(138,111,61,.22);border-radius:8px;padding:10px;background:rgba(255,248,232,.74)}.location-warning-list{margin:0;padding-left:18px;color:#6f5526;font-size:.86rem}.location-tree{display:grid;gap:8px}.location-tree-row{display:flex;align-items:center;justify-content:space-between;gap:12px;border-bottom:1px solid var(--plotline-line);padding:10px 0 10px calc(var(--location-depth,0)*22px)}.location-tree-row:last-child{border-bottom:0}.location-tree-row>div:first-child{display:grid;gap:3px}.compact-buttons{flex-wrap:nowrap}.location-chip-list{display:flex;flex-wrap:wrap;gap:8px}.location-chip{border:1px solid var(--plotline-line);border-radius:8px;padding:7px 10px;background:#fff;text-decoration:none}.location-relationship-list{display:grid;gap:8px}.location-relationship-card{display:flex;justify-content:space-between;gap:12px;border:1px solid var(--plotline-line);border-radius:8px;padding:10px;background:#fff}.location-flags{display:flex;flex-wrap:wrap;gap:10px 16px;color:var(--plotline-muted);font-size:.86rem}.validation-summary,.warning-filter-panel{border:1px solid var(--plotline-line);border-radius:8px;margin-bottom:16px;padding:12px;background:#fff}.validation-summary{display:flex;flex-wrap:wrap;gap:12px;color:var(--plotline-muted)}.warning-dashboard-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px;margin-bottom:18px}.warning-count-row,.warning-card-title,.inspector-section-heading{display:flex;align-items:center;justify-content:space-between;gap:10px}.warning-list,.warning-mini-list{display:grid;gap:10px}.warning-card,.warning-mini-card{border:1px solid var(--plotline-line);border-radius:8px;padding:12px;background:#fff}.warning-card{display:grid;grid-template-columns:1fr auto;gap:12px}.warning-card p,.warning-mini-card p{margin:6px 0}.warning-actions{display:flex;align-items:flex-start;flex-wrap:wrap;gap:6px}.severity-pill{display:inline-flex;align-items:center;border-radius:999px;padding:2px 8px;font-size:.74rem;font-weight:800}.severity-pill.info{color:#365f7c;background:rgba(107,153,184,.14)}.severity-pill.warning{color:#7a5527;background:rgba(205,154,72,.17)}.severity-pill.error{color:#8a3434;background:rgba(190,83,83,.15)}.warning-mini-card{background:rgba(255,255,255,.76)}.dependency-columns{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}.dependency-card{display:grid;gap:3px;border:1px solid var(--plotline-line);border-radius:8px;margin-bottom:8px;padding:9px;background:rgba(255,255,255,.78)}.move-preview-panel{max-width:900px}.focused-validation-summary{display:flex;flex-wrap:wrap;gap:10px;border:1px solid rgba(47,111,99,.16);border-radius:8px;margin-top:12px;padding:10px;color:var(--plotline-muted);background:rgba(47,111,99,.05)}.inspector-purpose-list{grid-template-columns:1fr;max-height:210px}.metric-slider-stack{display:grid;gap:12px}.metric-slider{display:grid;gap:4px}.metric-slider-label{display:flex;justify-content:space-between;gap:10px;color:var(--plotline-muted);font-size:.86rem;font-weight:700}.metric-slider-label output{color:var(--plotline-accent-dark)}.metric-slider .form-range{accent-color:var(--plotline-accent)}.asset-importance-slider{border:1px solid var(--plotline-line);border-radius:8px;padding:10px 12px;background:rgba(47,111,99,.05)}.story-asset-checkbox-field{margin-top:1.95rem}.story-asset-event-item{justify-content:flex-start;gap:8px}.story-asset-event-item .asset-event-marker{flex:0 0 auto;min-width:1.55rem;width:auto}.story-asset-event-details{min-width:0}.scene-inspector-root{display:grid;gap:12px}.scene-overview-card{display:grid;gap:10px;border:1px solid rgba(47,111,99,.18);border-radius:10px;padding:12px;background:linear-gradient(180deg,rgba(47,111,99,.08),rgba(255,255,255,.88))}.scene-overview-card h3{margin:0;font-size:1.05rem}.scene-overview-card .muted{display:flex;flex-wrap:wrap;gap:7px;margin:0}.overview-chip-grid,.context-nav,.breadcrumb-trail,.inspector-nav-links{display:flex;flex-wrap:wrap;gap:7px}.overview-chip,.context-nav a,.breadcrumb-trail a,.breadcrumb-trail span{display:inline-flex;align-items:center;border:1px solid var(--plotline-line);border-radius:999px;padding:4px 9px;color:var(--plotline-muted);font-size:.78rem;font-weight:800;text-decoration:none;background:rgba(255,255,255,.72)}.overview-chip.attention{color:#7a5527;border-color:rgba(205,154,72,.35);background:rgba(205,154,72,.14)}.overview-outcome{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;margin:0;color:var(--plotline-muted)}.inspector-quick-nav{position:sticky;top:0;z-index:5;display:grid;gap:8px;border:1px solid var(--plotline-line);border-radius:10px;padding:10px;background:rgba(255,255,255,.94);box-shadow:0 10px 24px rgba(55,48,39,.08);backdrop-filter:blur(8px)}.inspector-nav-links a{border:1px solid var(--plotline-line);border-radius:999px;padding:4px 8px;color:var(--plotline-muted);font-size:.76rem;font-weight:800;text-decoration:none}.inspector-nav-links a:hover,.inspector-nav-links a.active{color:var(--plotline-accent-dark);border-color:rgba(47,111,99,.35);background:rgba(47,111,99,.08)}.inspector-accordion-toggle{display:flex;align-items:center;justify-content:space-between;width:100%;border:0;padding:0;color:var(--plotline-ink);font-size:.95rem;font-weight:900;text-align:left;background:transparent}.inspector-accordion-toggle::before{content:"+";display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;border-radius:999px;margin-right:7px;color:var(--plotline-accent-dark);background:rgba(47,111,99,.09)}.inspector-section.is-open>.inspector-accordion-toggle::before{content:"-"}.inspector-accordion-toggle span:first-child{margin-right:auto}.accordion-count{color:var(--plotline-muted);font-size:.75rem}.inspector-subheading{margin:14px 0 8px;color:var(--plotline-muted);font-size:.88rem;font-weight:900}.inspector-accordion-body{display:none;margin-top:12px}.inspector-section.is-open>.inspector-accordion-body{display:block}.inspector-section.is-filtered-out{display:none}.breadcrumb-trail{margin-bottom:12px}.breadcrumb-trail a:hover,.context-nav a:hover{color:var(--plotline-accent-dark);border-color:rgba(47,111,99,.35);background:rgba(47,111,99,.08)}.context-header,.working-context-banner{display:flex;align-items:center;justify-content:space-between;gap:14px;border:1px solid var(--plotline-line);border-radius:10px;margin-bottom:16px;padding:10px 12px;background:rgba(255,255,255,.84);box-shadow:0 10px 24px rgba(55,48,39,.05)}.context-title{display:grid;gap:2px}.context-title strong{color:var(--plotline-ink)}.health-kpi-grid,.analytics-grid-two,.analytics-grid-three{display:grid;gap:14px;margin:18px 0}.health-kpi-grid{grid-template-columns:repeat(4,minmax(0,1fr))}.health-kpi-grid .plain-card{display:grid;gap:4px}.health-kpi-grid strong{color:var(--plotline-ink);font-size:2rem;line-height:1}.analytics-grid-two{grid-template-columns:repeat(2,minmax(0,1fr))}.analytics-grid-three{grid-template-columns:repeat(3,minmax(0,1fr))}.analytics-section{border:1px solid var(--plotline-line);border-radius:10px;margin:18px 0;padding:16px;background:rgba(255,255,255,.84);box-shadow:0 14px 34px rgba(55,48,39,.07)}.analytics-section-heading{display:flex;align-items:baseline;justify-content:space-between;gap:12px;margin-bottom:14px}.analytics-section-heading h2,.plain-card h3{margin:0}.analytics-metric-stack{display:grid;gap:12px;overflow-x:auto;padding-bottom:4px}.metric-shape-chart{display:grid;gap:12px}.metric-shape-intro{max-width:760px;margin:0;color:var(--plotline-muted)}.metric-toggle-row{display:flex;flex-wrap:wrap;gap:8px}.metric-toggle-pill{display:inline-flex;align-items:center;gap:6px;border:1px solid rgba(82,75,65,.16);border-radius:999px;padding:5px 9px;color:var(--plotline-muted);font-size:.78rem;font-weight:800;background:rgba(255,255,255,.78);cursor:pointer}.metric-toggle-pill::before{content:"";width:10px;height:10px;border-radius:999px;background:var(--metric-colour)}.metric-toggle-pill input{margin:0;accent-color:var(--metric-colour)}.timeline-metric-edit-toolbar{display:flex;flex-wrap:wrap;gap:8px;align-items:end}.timeline-metric-edit-select{display:grid;gap:3px;min-width:180px;color:var(--plotline-muted);font-size:.78rem;font-weight:800}.timeline-metric-edit-status{align-self:center;border:1px solid rgba(47,111,99,.18);border-radius:999px;padding:5px 9px;color:var(--plotline-muted);font-size:.78rem;font-weight:800;background:rgba(255,255,255,.72)}.timeline-metric-edit-hint{font-size:.82rem}.metric-chart-frame canvas.metric-curve-editing{cursor:ns-resize}.metric-chart-frame{position:relative;min-height:320px;border:1px solid var(--plotline-line);border-radius:10px;padding:14px 12px 32px;background:linear-gradient(180deg,rgba(255,255,255,.92),rgba(247,245,240,.76))}.metric-timeline-frame{width:calc((var(--scene-count)*var(--timeline-scene-width)) + ((var(--scene-count) - 1)*var(--timeline-grid-gap)))}.metric-chart-frame canvas{width:100%;height:300px}.metric-timeline-board .metric-graph-stack{width:max-content;min-width:100%}.metric-timeline-board .metric-graph-row{grid-template-columns:var(--timeline-label-width) repeat(var(--scene-count),var(--timeline-scene-width));gap:var(--timeline-grid-gap);min-width:100%}.metric-timeline-board .metric-graph-points{display:contents}.metric-timeline-board .metric-point{border:1px solid rgba(47,111,99,.12);border-radius:8px;background:rgba(255,255,255,.62)}.metric-raw-details{border-top:1px solid var(--plotline-line);padding-top:8px}.metric-raw-details summary{color:var(--plotline-muted);font-size:.82rem;font-weight:800;cursor:pointer}.timeline-control-panel{display:grid;gap:12px;border:1px solid var(--plotline-line);border-radius:10px;margin-bottom:16px;padding:12px;background:rgba(255,255,255,.84);box-shadow:0 10px 24px rgba(55,48,39,.05)}.timeline-filter-drawer summary{color:var(--plotline-ink);font-weight:900;cursor:pointer}.timeline-filter-grid{display:grid;grid-template-columns:repeat(6,minmax(130px,1fr));gap:10px;margin-top:12px}.timeline-filter-checks,.timeline-filter-actions,.timeline-visibility-panel,.timeline-preset-panel,.preset-chip-row{display:flex;flex-wrap:wrap;align-items:center;gap:8px}.timeline-filter-checks{grid-column:span 3;color:var(--plotline-muted);font-size:.82rem;font-weight:700}.timeline-filter-actions{grid-column:span 3;justify-content:flex-end}.timeline-visibility-panel label,.preset-chip{display:inline-flex;align-items:center;gap:6px;border:1px solid var(--plotline-line);border-radius:999px;padding:4px 8px;color:var(--plotline-muted);font-size:.78rem;font-weight:800;background:rgba(255,255,255,.76)}.timeline-preset-panel form{display:inline-flex;align-items:center;gap:6px}.preset-chip a{color:var(--plotline-accent-dark);text-decoration:none}.preset-chip button{border:0;color:var(--plotline-muted);background:transparent;font-weight:900}.timeline-focus-banner{display:flex;align-items:center;justify-content:space-between;gap:12px;border:1px solid rgba(47,111,99,.22);border-radius:10px;margin-bottom:16px;padding:10px 12px;background:rgba(47,111,99,.08)}.thread-marker-icon{display:inline-flex;align-items:center;justify-content:center;min-width:16px;font-size:.78rem;font-weight:900}.thread-marker-type-start .thread-marker-icon,.thread-marker-type-resolve .thread-marker-icon,.thread-marker-type-abandon .thread-marker-icon,.thread-marker-type-twist .thread-marker-icon{font-size:.9rem}.thread-marker-type-start{border-radius:8px 999px 999px 8px}.thread-marker-type-twist{border-color:#b8762b;background:#fff4dc}.thread-marker-type-branch,.thread-marker-type-split,.thread-marker-type-merge{border-color:#6750a4;background:#f0ebff}.thread-marker-type-reveal .thread-marker-icon{border:1px solid currentColor;border-radius:999px;font-size:0}.thread-marker-type-reveal .thread-marker-icon::after{content:"";width:4px;height:4px;border-radius:999px;background:currentColor}.timeline-navigation-card{display:grid;grid-template-areas:"icon copy" "icon actions";grid-template-columns:auto minmax(0,620px);gap:8px 14px;align-items:center;justify-content:center;border:1px solid rgba(47,111,99,.42);border-left:5px solid var(--plotline-accent);border-radius:8px;margin:0 0 12px;padding:14px 16px;max-height:280px;overflow:hidden;color:var(--plotline-ink);background:linear-gradient(135deg,rgba(238,245,242,.98),rgba(255,255,255,.94));box-shadow:0 10px 26px rgba(30,37,43,.08);opacity:1;transform:translateY(0);transition:opacity 1.15s ease,max-height 1.2s ease,margin 1.2s ease,padding 1.2s ease,transform 1.15s ease}.timeline-navigation-card[hidden]{display:none}.timeline-navigation-card.is-dismissing{margin-bottom:0;padding-top:0;padding-bottom:0;max-height:0;opacity:0;transform:translateY(-6px)}.timeline-navigation-card-icon{grid-area:icon;display:grid;place-items:center;width:42px;height:42px;border-radius:50%;color:#fff;background:var(--plotline-accent);font-size:1.25rem;font-weight:900}.timeline-navigation-card-copy{grid-area:copy;text-align:center}.timeline-navigation-card-copy h2{margin:0 0 6px;color:var(--plotline-accent-dark);font-size:1rem;font-weight:900}.timeline-navigation-card-copy p{margin:2px 0;color:var(--plotline-ink);font-size:.9rem}.timeline-navigation-card-actions{grid-area:actions;display:flex;flex-wrap:wrap;gap:8px;justify-content:center}.timeline-horizontal-overflow{transition:box-shadow .18s ease}.timeline-horizontal-overflow.has-scroll-left{box-shadow:inset 18px 0 18px -20px rgba(30,37,43,.55)}.timeline-horizontal-overflow.has-scroll-right{box-shadow:inset -18px 0 18px -20px rgba(30,37,43,.55)}.timeline-horizontal-overflow.has-scroll-left.has-scroll-right{box-shadow:inset 18px 0 18px -20px rgba(30,37,43,.55),inset -18px 0 18px -20px rgba(30,37,43,.55)}[data-theme="dark"] .timeline-navigation-card{border-color:rgba(111,169,155,.52);border-left-color:#6fa99b;color:#f4eadc;background:linear-gradient(135deg,rgba(34,83,74,.72),rgba(32,31,34,.96));box-shadow:0 12px 28px rgba(0,0,0,.28)}[data-theme="dark"] .timeline-navigation-card-copy h2,[data-theme="dark"] .timeline-navigation-card-copy p{color:#f4eadc}[data-theme="dark"] .timeline-horizontal-overflow.has-scroll-left{box-shadow:inset 18px 0 18px -20px rgba(244,234,220,.55)}[data-theme="dark"] .timeline-horizontal-overflow.has-scroll-right{box-shadow:inset -18px 0 18px -20px rgba(244,234,220,.55)}[data-theme="dark"] .timeline-horizontal-overflow.has-scroll-left.has-scroll-right{box-shadow:inset 18px 0 18px -20px rgba(244,234,220,.55),inset -18px 0 18px -20px rgba(244,234,220,.55)}@media(prefers-reduced-motion:reduce){.timeline-navigation-card{transition:opacity .12s ease}}.timeline-scene-card.filter-dim,.timeline-scene-card.focus-dim,.lane-dim{opacity:.35}.timeline-scene-card.focus-match,.timeline-scene-card.filter-match.focus-match{outline:3px solid rgba(47,111,99,.32);box-shadow:0 12px 26px rgba(47,111,99,.16)}.timeline-section-hidden{display:none!important}.hide-scene-cards .timeline-scene-card{display:none}.timeline-control-panel{position:sticky;top:56px;z-index:18}.timeline-control-select{padding-right:6px}.timeline-control-select .form-select{width:auto;min-width:132px;border:0;padding-top:2px;padding-bottom:2px;background-color:transparent;color:var(--plotline-accent-dark);font-weight:800}.timeline-jump-panel{display:grid;grid-template-columns:auto minmax(180px,1.2fr) minmax(180px,1fr) minmax(170px,.9fr) minmax(180px,1fr) auto;gap:8px;align-items:center;width:100%}.timeline-shortcut-hint{color:var(--plotline-muted);font-size:.76rem;font-weight:700;white-space:nowrap}.timeline-minimap{display:flex;align-items:stretch;gap:4px;margin:0 0 12px;padding:8px;max-width:100%;min-width:0;overflow-x:auto;overflow-y:hidden;overscroll-behavior-x:contain;scrollbar-gutter:stable;border:1px solid rgba(47,111,99,.18);border-radius:8px;background:rgba(255,255,255,.72)}.timeline-minimap button{position:relative;flex:0 0 max(42px,calc(var(--chapter-scenes)*18px));min-width:42px;min-height:34px;border:1px solid rgba(47,111,99,.18);border-radius:7px;color:var(--plotline-accent-dark);background:linear-gradient(180deg,#f8fbf9 0%,#edf4f1 100%);font-size:.72rem;font-weight:800}.timeline-minimap button.is-active{border-color:var(--plotline-accent);color:#fff;background:linear-gradient(180deg,var(--plotline-accent) 0%,var(--plotline-accent-dark) 100%);box-shadow:0 0 0 2px rgba(47,111,99,.14)}.timeline-minimap button::after{content:"";position:absolute;right:5px;bottom:5px;width:calc(var(--chapter-warnings)*4px);max-width:28px;height:4px;border-radius:999px;background:#b45c5c;opacity:.75}.timeline-drag-palette,.drag-drop-panel{border:1px solid rgba(47,111,99,.18);border-radius:10px;margin-bottom:12px;padding:12px;background:rgba(255,255,255,.84);box-shadow:0 10px 24px rgba(55,48,39,.05)}.timeline-drag-palette{display:grid;grid-template-columns:minmax(220px,.35fr) minmax(0,1fr);gap:12px;align-items:center}.drag-chip-group{display:flex;flex-wrap:wrap;gap:6px;max-height:104px;overflow:auto;padding-right:4px}.drag-chip{display:inline-flex;align-items:center;border:1px solid var(--plotline-line);border-radius:999px;padding:4px 9px;background:#fff;color:var(--plotline-ink);font-size:.78rem;font-weight:800;cursor:grab}.drag-chip.character{border-color:#dacb9e;background:#fff8e8}.drag-chip.asset{border-color:#ded9ea;background:#f4f0ff}.drag-chip.location{border-color:rgba(47,111,99,.18);background:#eef8f4}.is-dragging{opacity:.55}.drop-target-active{outline:3px solid rgba(47,111,99,.28);outline-offset:2px}.timeline-chapter.chapter-drop-active,.timeline-scenes.drop-chapter-end{background:rgba(47,111,99,.06)}.timeline-scenes.drop-chapter-end::after{content:"Drop scene at end of chapter";display:flex;align-items:center;justify-content:center;min-width:var(--timeline-scene-width);min-height:74px;border:2px dashed rgba(197,139,43,.48);border-radius:12px;color:#7a5527;background:rgba(255,248,232,.82);font-size:.8rem;font-weight:900}.timeline-scene-card.drop-before{box-shadow:inset 5px 0 0 #c58b2b,0 12px 26px rgba(197,139,43,.16)}.timeline-scene-card.drop-after{box-shadow:inset -5px 0 0 #c58b2b,0 12px 26px rgba(197,139,43,.16)}.drag-drop-panel{position:sticky;top:132px;z-index:19}.drag-drop-panel-header{display:flex;align-items:flex-start;justify-content:space-between;gap:12px}.drag-drop-panel h2{margin:0;font-size:1.08rem}.drag-drop-form{border-top:1px solid var(--plotline-line);margin-top:10px;padding-top:10px}.scene-move-modal-content{border:1px solid rgba(47,111,99,.18);border-radius:14px;background:var(--plotline-surface);color:var(--plotline-ink);box-shadow:0 24px 70px rgba(55,48,39,.22)}.scene-move-modal-content .modal-header,.scene-move-modal-content .modal-footer{border-color:var(--plotline-line)}.scene-move-modal-content .modal-title{margin:0;color:var(--plotline-ink);font-size:1.2rem;font-weight:900}.scene-move-summary{margin:0 0 12px;color:var(--plotline-ink);font-size:1rem;font-weight:800}[data-theme="dark"] .scene-move-modal-content{background:#201f22;color:#f4eadc;border-color:rgba(244,234,220,.16);box-shadow:0 24px 70px rgba(0,0,0,.55)}[data-theme="dark"] .scene-move-modal-content .modal-title,[data-theme="dark"] .scene-move-summary{color:#f4eadc}[data-theme="dark"] .scene-move-modal-content .modal-header,[data-theme="dark"] .scene-move-modal-content .modal-footer{border-color:rgba(244,234,220,.14)}[data-theme="dark"] .scene-move-modal-content .btn-close{filter:invert(1) grayscale(100%)}.plain-preview{border:1px solid rgba(197,139,43,.28);border-radius:8px;margin:10px 0 0;padding:8px 10px;color:#5e4518;background:#fff8e8;font-size:.86rem;font-weight:800}.drag-check-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px 10px;color:var(--plotline-muted);font-size:.82rem;font-weight:700}.timeline-section-header,.lane-board-heading,.pacing-heading{position:sticky;left:0;z-index:6}.timeline-section-header{display:flex;align-items:center;justify-content:space-between;gap:10px;width:calc(var(--timeline-label-width) + (var(--scene-count)*var(--timeline-scene-width)) + (var(--scene-count)*var(--timeline-grid-gap)));min-width:100%;margin-bottom:10px;border-radius:8px;padding:8px 10px;background:rgba(255,255,255,.92);box-shadow:0 8px 16px rgba(30,37,43,.05)}.timeline-section-header button,.lane-board-heading button,.plot-lane-board-heading button,.pacing-heading button,.lane-group-heading{border:0;padding:0;color:var(--plotline-accent-dark);background:transparent;font:inherit;font-weight:900;text-align:left}.timeline-section-header button::before,.lane-board-heading button::before,.plot-lane-board-heading button::before,.pacing-heading button::before,.lane-group-heading::before{content:"v";display:inline-block;margin-right:6px;color:var(--plotline-muted);font-size:.72rem}.timeline-section-header button.is-collapsed::before,.lane-board-heading button.is-collapsed::before,.plot-lane-board-heading button.is-collapsed::before,.pacing-heading button.is-collapsed::before,.lane-group-heading.is-collapsed::before{content:">"}.lane-group{display:grid;gap:7px}.character-lane-group-body{display:grid;gap:7px}.lane-group-heading{position:sticky;left:0;z-index:6;width:var(--timeline-label-width);border-top:1px solid rgba(47,111,99,.12);padding:7px 8px 2px;color:var(--plotline-muted);background:rgba(247,250,248,.96);font-size:.78rem;text-transform:uppercase}.timeline-section-collapsed{display:none!important}.timeline-chapter-title{position:sticky;top:0;z-index:5;background:rgba(238,245,242,.96);backdrop-filter:blur(6px)}.scene-pov-label,.metric-mini-summary{display:inline-flex;width:fit-content;border-radius:999px;padding:2px 7px;font-size:.72rem;font-weight:800}.scene-pov-label{color:#514018;background:#fff3d3}.metric-mini-summary{color:var(--plotline-accent-dark);background:rgba(47,111,99,.08)}.scene-overview-panel{display:none;gap:8px;margin-top:4px}.scene-overview-section{display:grid;gap:4px}.scene-overview-label{color:var(--plotline-muted);font-size:.68rem;font-weight:900;letter-spacing:.06em;text-transform:uppercase}.scene-overview-chip-row{display:flex;flex-wrap:wrap;gap:5px;min-width:0}.scene-overview-chip,.scene-overview-empty,.scene-overview-brief{display:inline-flex;width:fit-content;max-width:100%;border-radius:999px;padding:3px 8px;background:rgba(47,111,99,.08);color:var(--plotline-ink);font-size:.72rem;font-weight:750;line-height:1.25;overflow-wrap:anywhere}.scene-overview-chip.is-pov{border:1px solid rgba(197,139,43,.38);background:#fff3d3}.scene-overview-chip.is-important{border:1px solid rgba(103,80,164,.3);background:#f0edf8}.scene-overview-chip.is-more,.scene-overview-empty{color:var(--plotline-muted);background:rgba(102,113,123,.08)}.scene-overview-brief{display:block;width:auto;border-radius:8px;background:rgba(255,255,255,.62);color:var(--plotline-muted);font-weight:600}.timeline-scene-card.search-hit,.timeline-scene-card.keyboard-focus{outline:3px solid rgba(197,139,43,.34);box-shadow:0 12px 26px rgba(197,139,43,.16)}.timeline-scene-card.search-dim{opacity:.28}.thread-marker,.asset-marker,.character-marker{transition:transform .12s ease,box-shadow .12s ease}.thread-marker:hover,.asset-marker:hover,.character-marker:hover{transform:translateY(-1px);box-shadow:0 6px 12px rgba(30,37,43,.12)}.timeline-filtered-root.density-compact{--timeline-scene-width:170px;--timeline-grid-gap:6px}.timeline-filtered-root.density-expanded{--timeline-scene-width:280px;--timeline-grid-gap:14px}.timeline-filtered-root.density-compact .timeline-scene-card,.timeline-filtered-root.zoom-book .timeline-scene-card{gap:4px;padding:9px}.timeline-filtered-root.density-compact .scene-summary,.timeline-filtered-root.density-compact .purpose-chip-row,.timeline-filtered-root.density-compact .metric-mini-summary,.timeline-filtered-root.zoom-book .scene-summary,.timeline-filtered-root.zoom-book .purpose-chip-row,.timeline-filtered-root.zoom-book .metric-mini-summary,.timeline-filtered-root.zoom-book .location-pill,.timeline-filtered-root.zoom-book .scene-pov-label{display:none}.timeline-filtered-root.zoom-book{--timeline-scene-width:150px;--timeline-grid-gap:6px}.timeline-filtered-root.zoom-scene-detail{--timeline-scene-width:300px}.timeline-filtered-root.zoom-scene-detail .scene-summary{-webkit-line-clamp:7}.timeline-filtered-root.zoom-scene-overview{--timeline-scene-width:380px}.timeline-filtered-root.zoom-scene-overview .timeline-scenes{min-height:320px}.timeline-filtered-root.zoom-scene-overview .timeline-scene-card{gap:8px;padding:14px}.timeline-filtered-root.zoom-scene-overview .scene-summary{display:none}.timeline-filtered-root.zoom-scene-overview .scene-overview-panel{display:grid}.timeline-filtered-root.density-expanded .timeline-scenes{min-height:230px}.timeline-control-panel{position:relative;top:auto;z-index:4;display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin-bottom:10px;padding:8px;box-shadow:none}.timeline-filter-drawer,.timeline-control-group{border:1px solid var(--plotline-line);border-radius:999px;background:rgba(255,255,255,.82)}.timeline-filter-drawer[open],.timeline-control-group[open]{border-radius:10px;flex-basis:100%}.timeline-filter-drawer summary,.timeline-control-group summary{min-width:max-content;padding:5px 10px;color:var(--plotline-accent-dark);font-size:.82rem;font-weight:900;cursor:pointer;list-style:none}.timeline-filter-drawer summary::-webkit-details-marker,.timeline-control-group summary::-webkit-details-marker,.timeline-drag-palette summary::-webkit-details-marker{display:none}.timeline-filter-drawer summary::after,.timeline-control-group summary::after,.timeline-drag-palette summary::after{content:" v";color:var(--plotline-muted);font-size:.72rem}.timeline-filter-drawer[open] summary::after,.timeline-control-group[open] summary::after,.timeline-drag-palette[open] summary::after{content:" ^"}.timeline-filter-grid{grid-template-columns:repeat(auto-fit,minmax(145px,1fr));gap:8px;max-height:min(48vh,430px);overflow:auto;padding:0 10px 10px}.timeline-filter-grid .form-label{margin-bottom:2px;font-size:.72rem;font-weight:800}.timeline-filter-checks,.timeline-filter-actions{grid-column:1/-1}.timeline-visibility-panel,.timeline-jump-panel,.timeline-preset-panel{padding:0 10px 10px}.timeline-jump-panel{grid-template-columns:minmax(180px,1.5fr) repeat(3,minmax(150px,1fr))}.timeline-shortcut-hint{grid-column:1/-1}.timeline-preset-panel form{flex-wrap:nowrap}.timeline-preset-panel .form-control{width:150px}.timeline-preset-panel .btn,.timeline-filter-actions .btn{white-space:nowrap}.timeline-drag-palette{display:block;margin-bottom:8px;padding:7px 9px;box-shadow:none}.timeline-drag-palette summary{color:var(--plotline-accent-dark);font-size:.82rem;font-weight:900;cursor:pointer}.timeline-drag-palette .drag-chip-group{margin-top:8px}.drag-drop-panel{position:relative;top:auto;z-index:9;box-shadow:0 12px 28px rgba(30,37,43,.08)}.timeline-filtered-root,.timeline-filtered-root.density-compact,.timeline-filtered-root.zoom-book{--timeline-scene-width:220px;--timeline-grid-gap:10px}.timeline-filtered-root.density-expanded,.timeline-filtered-root.zoom-scene-detail{--timeline-scene-width:290px}.timeline-filtered-root.density-compact.zoom-book{--timeline-scene-width:200px}.timeline-chapter,.timeline-scene-card,.timeline-empty-scene{overflow-wrap:normal;word-break:normal}.timeline-scene-card strong,.timeline-chapter-title strong,.plot-lane-label strong,.asset-lane-label strong,.character-lane-label strong{min-width:0;white-space:normal;word-break:normal;overflow-wrap:break-word}.timeline-scene-card{cursor:grab}.timeline-scene-card:active,.drag-chip:active,[draggable="true"]:active{cursor:grabbing}body.drag-active .timeline-scene-card,body.dragging-asset [data-asset-drop-target],body.dragging-location [data-drag-type="location"]{transition:outline-color .12s ease,box-shadow .12s ease,opacity .12s ease}body.dragging-character .timeline-scene-card,body.dragging-asset .timeline-scene-card,body.dragging-scene .timeline-scene-card,body.dragging-scene .timeline-scenes[data-chapter-drop-target],body.dragging-asset [data-asset-drop-target],body.dragging-location [data-drag-type="location"]{outline:1px dashed rgba(47,111,99,.22);outline-offset:2px}.is-dragging{opacity:.42;transform:scale(.98)}.drop-target-active{outline:3px solid rgba(47,111,99,.42)!important;outline-offset:3px}.analytics-metric-row{display:grid;grid-template-columns:170px minmax(560px,1fr);gap:12px;align-items:stretch}.analytics-metric-label{display:flex;align-items:center;border-right:1px solid var(--plotline-line);color:var(--plotline-muted);font-weight:800}.analytics-sparkline{display:grid;grid-template-columns:repeat(var(--point-count),minmax(28px,1fr));align-items:end;gap:5px;min-height:88px;border-bottom:1px solid rgba(47,111,99,.25);padding-top:10px}.analytics-bar{position:relative;display:flex;align-items:end;justify-content:center;min-height:12px;height:max(12px,var(--bar-height));border-radius:6px 6px 2px 2px;color:var(--plotline-accent-dark);text-decoration:none;background:linear-gradient(180deg,rgba(47,111,99,.58),rgba(47,111,99,.18))}.analytics-bar:hover{background:linear-gradient(180deg,rgba(47,111,99,.82),rgba(47,111,99,.28))}.analytics-bar span{position:absolute;bottom:calc(100% + 3px);color:var(--plotline-muted);font-size:.68rem;font-weight:800}.analytics-list-item,.analytics-link-row,.analytics-count-row,.purpose-stat-row{border-top:1px solid var(--plotline-line);padding:9px 0}.analytics-list-item{display:grid;gap:3px}.analytics-list-item p{margin:0}.analytics-link-row,.analytics-count-row{display:flex;align-items:center;justify-content:space-between;gap:12px}.analytics-link-row{color:inherit;text-decoration:none}.analytics-link-row:hover{color:var(--plotline-accent-dark)}.analytics-link-row span,.analytics-link-row strong{min-width:0}.purpose-stat-row{display:grid;grid-template-columns:minmax(120px,1fr) minmax(90px,1.5fr) 42px;align-items:center;gap:10px}.purpose-stat-bar{overflow:hidden;height:8px;border-radius:999px;background:rgba(47,111,99,.08)}.purpose-stat-bar span{display:block;height:100%;border-radius:inherit;background:var(--plotline-accent)}.inspector-actions{position:sticky;bottom:-16px;display:flex;gap:8px;border-top:1px solid var(--plotline-line);margin:2px -16px -16px;padding:12px 16px;background:rgba(255,255,255,.95);backdrop-filter:blur(8px)}.story-bible-heading{align-items:end}.story-bible-search{display:flex;gap:8px;min-width:min(100%,420px)}.story-bible-search .form-control{min-width:0}.story-bible-nav{position:sticky;top:72px;z-index:4;display:flex;flex-wrap:wrap;gap:8px;margin:0 0 18px;padding:10px;border:1px solid var(--plotline-line);border-radius:12px;background:rgba(250,249,246,.92);backdrop-filter:blur(10px)}.story-bible-nav a,.story-bible-actions a{display:inline-flex;align-items:center;border-radius:999px;padding:6px 10px;background:rgba(47,111,99,.08);color:var(--plotline-ink);font-size:.86rem;font-weight:650;text-decoration:none}.story-bible-nav a:hover,.story-bible-actions a:hover{background:rgba(47,111,99,.16)}.story-bible-section{margin:0 0 28px}.story-bible-section-heading{display:flex;align-items:end;justify-content:space-between;gap:16px;margin-bottom:12px}.story-bible-section-heading h2{margin:0}.soft-count{color:var(--plotline-muted);font-size:.9rem;font-weight:650;white-space:nowrap}.story-bible-grid,.story-bible-search-results{display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:14px}.story-bible-grid-compact{grid-template-columns:repeat(auto-fit,minmax(260px,1fr))}.story-bible-card{border:1px solid var(--plotline-line);border-radius:14px;padding:14px;background:rgba(255,255,255,.86);box-shadow:0 14px 34px rgba(36,32,26,.06)}.story-bible-card h3{margin:0 0 8px;font-size:1.05rem}.story-bible-card h4{margin:14px 0 8px;font-size:.96rem}.story-bible-card p{color:var(--plotline-muted)}.story-bible-card-title{display:flex;align-items:start;justify-content:space-between;gap:10px}.story-bible-card-title span{border:1px solid var(--plotline-line);border-radius:999px;padding:3px 8px;background:rgba(250,249,246,.9);color:var(--plotline-muted);font-size:.78rem;font-weight:700;white-space:nowrap}.story-bible-meta{display:flex;flex-wrap:wrap;gap:6px;margin:10px 0}.story-bible-meta span{border-radius:999px;padding:4px 8px;background:rgba(36,32,26,.05);color:var(--plotline-muted);font-size:.78rem;font-weight:650}.story-bible-facts{display:grid;grid-template-columns:max-content minmax(0,1fr);gap:6px 10px;margin:12px 0}.story-bible-facts dt{color:var(--plotline-muted);font-size:.78rem;font-weight:800;text-transform:uppercase}.story-bible-facts dd{margin:0;min-width:0;overflow-wrap:anywhere}.story-bible-actions{display:flex;flex-wrap:wrap;gap:8px;margin-top:12px}.story-bible-link-list{display:grid;gap:8px;margin:0;padding:0;list-style:none}.story-bible-link-list li{display:grid;gap:2px;padding:8px 0;border-bottom:1px solid rgba(36,32,26,.08)}.story-bible-link-list li:last-child{border-bottom:0}.story-bible-link-list span{color:var(--plotline-muted);font-size:.88rem}.story-bible-timeline-summary{display:grid;gap:14px}.story-bible-wide-card{max-width:none}.story-bible-chapter-summary{border-top:1px solid var(--plotline-line);padding-top:8px}.story-bible-scene-summary{display:grid;grid-template-columns:minmax(220px,1.5fr) repeat(3,minmax(120px,.8fr));gap:8px;padding:9px 0;border-top:1px solid rgba(36,32,26,.08)}.story-bible-scene-summary p{grid-column:1/-1;margin:0}.story-bible-scene-summary span{color:var(--plotline-muted);font-size:.88rem}.attention-list{display:grid;gap:10px}.attention-list article{display:grid;grid-template-columns:max-content minmax(0,1fr) auto;align-items:center;gap:10px;border:1px solid var(--plotline-line);border-radius:12px;padding:10px 12px;background:rgba(255,255,255,.82)}.attention-list p{grid-column:2/-1;margin:0;color:var(--plotline-muted)}.writer-workspace-form,.writer-add-form,.writer-edit-form,.chapter-goal-form{display:grid;gap:10px}.writer-checkbox-grid{display:flex;flex-wrap:wrap;gap:8px 14px}.writer-checkbox-grid label{display:inline-flex;align-items:center;gap:6px;color:var(--plotline-muted);font-size:.86rem;font-weight:650}.writer-priority-control{display:grid;grid-template-columns:minmax(0,1fr) max-content;align-items:center;gap:12px}.writer-priority-control .form-range{min-width:0}.writer-note-list,.writer-queue-list{display:grid;gap:10px}.writer-mini-card{border:1px solid var(--plotline-line);border-radius:12px;padding:10px;background:rgba(255,255,255,.72)}.writer-mini-card summary{display:flex;align-items:center;gap:8px;cursor:pointer}.writer-mini-card summary strong{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.attachment-card-list{display:grid;gap:10px}.attachment-summary{align-items:center}.attachment-kind{border-radius:999px;padding:3px 8px;background:rgba(47,111,99,.1);color:var(--plotline-accent);font-size:.76rem;font-weight:800;text-transform:uppercase}.attachment-card-body{display:grid;gap:6px;margin-top:10px}.attachment-card-body p{margin:0}.attachment-add-card{margin-top:10px}.writer-checklist{display:grid;gap:6px}.writer-checklist-row,.writer-add-inline{display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:8px}.writer-remove-inline{display:flex;justify-content:end;margin:-2px 0 4px}.writer-dashboard-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px;margin-bottom:26px}.writer-dashboard-panel{border:1px solid var(--plotline-line);border-radius:14px;padding:14px;background:rgba(255,255,255,.7);box-shadow:0 14px 34px rgba(36,32,26,.05)}.writer-queue-card{border:1px solid var(--plotline-line);border-radius:12px;padding:12px;background:rgba(255,255,255,.9)}.writer-queue-card h3{margin:0;font-size:1rem}.writer-queue-card p{margin:8px 0 0;color:var(--plotline-muted)}.writer-queue-title{display:flex;align-items:start;justify-content:space-between;gap:12px}.writer-kpi{display:block;color:var(--plotline-accent);font-size:2.2rem;line-height:1}.export-action-row{margin:-8px 0 18px}.dynamics-timeline{position:relative;min-height:128px;border:1px solid var(--plotline-line);border-radius:14px;background:linear-gradient(180deg,rgba(47,111,99,.07),rgba(255,255,255,.84));overflow:hidden}.dynamics-timeline::before{content:"";position:absolute;left:12px;right:12px;top:64px;height:1px;background:rgba(36,32,26,.18)}.dynamics-marker{position:absolute;bottom:18px;width:12px;height:86px;transform:translateX(-50%);display:flex;align-items:end;justify-content:center}.dynamics-marker span{display:block;width:8px;min-height:12px;max-height:82px;border-radius:999px;background:var(--plotline-accent);box-shadow:0 8px 20px rgba(47,111,99,.22)}.dynamics-marker.pov span{background:#8a4b2f}.dynamics-timeline.relationship .dynamics-marker span{background:#7c5fb0}.scenario-banner{display:flex;justify-content:space-between;gap:18px;align-items:flex-start;border:1px solid rgba(103,80,164,.22);border-radius:12px;padding:16px;margin-bottom:16px;background:linear-gradient(135deg,rgba(103,80,164,.1),rgba(255,255,255,.86));box-shadow:0 12px 28px rgba(36,32,26,.08)}.scenario-banner h1{margin:0 0 4px}.scenario-banner p{margin:0;color:var(--plotline-muted)}.scenario-card{border-color:rgba(103,80,164,.18)}.scenario-warning-strip{display:flex;gap:10px;align-items:center;border:1px solid var(--plotline-line);border-radius:10px;padding:10px 12px;margin-bottom:14px;background:rgba(255,255,255,.76);color:var(--plotline-muted)}.scenario-warning-strip strong{color:var(--plotline-ink)}.scenario-board{border:1px solid var(--plotline-line);border-radius:12px;padding:12px;background:rgba(247,245,240,.74);overflow:hidden;margin-bottom:18px}.scenario-scroll{display:flex;gap:14px;overflow-x:auto;padding-bottom:8px}.scenario-chapter{min-width:360px;max-width:520px;border:1px solid rgba(82,75,65,.14);border-radius:10px;background:rgba(255,255,255,.86)}.scenario-chapter header{display:grid;gap:2px;border-bottom:1px solid var(--plotline-line);padding:10px 12px}.scenario-chapter header span{color:var(--plotline-muted);font-size:.78rem;font-weight:800;text-transform:uppercase}.scenario-scene-row{display:grid;gap:10px;padding:10px}.scenario-scene-card{display:grid;gap:8px;border:1px solid rgba(82,75,65,.12);border-radius:9px;padding:10px;background:#fff}.scenario-scene-title{display:grid;gap:2px}.scenario-scene-title span,.scenario-mini-data{color:var(--plotline-muted);font-size:.78rem}.scenario-mini-data{display:grid;gap:2px}.scenario-move-actions,.scenario-chapter-form,.scenario-compare-list article{display:flex;gap:8px;flex-wrap:wrap;align-items:center}.scenario-chapter-form select{min-width:160px;width:auto}.scenario-compare-list{display:grid;gap:10px}.scenario-compare-list article{justify-content:space-between;border:1px solid var(--plotline-line);border-radius:9px;padding:10px;background:rgba(255,255,255,.82)}.danger-zone{border-color:rgba(163,61,61,.24)}.archive-filter-form{align-items:end}.archive-item-list{display:grid;gap:10px}.archive-item-card{display:flex;justify-content:space-between;gap:14px;align-items:center;border:1px solid var(--plotline-line);border-radius:10px;padding:12px;background:rgba(255,255,255,.82)}.archive-actions{display:flex;flex-wrap:wrap;gap:8px;align-items:center;justify-items:end}.delete-forever-form{display:inline-flex;margin:0}.archive-item-card h3{margin:4px 0}.archived-badge{display:inline-flex;border:1px solid rgba(82,75,65,.16);border-radius:999px;padding:2px 8px;color:var(--plotline-muted);font-size:.72rem;font-weight:800;text-transform:uppercase;background:rgba(247,245,240,.86)}.restore-button{white-space:nowrap}.archive-button-form{display:inline-flex;align-items:center;margin:0}.acceptance-summary-grid{display:grid;grid-template-columns:repeat(3,minmax(160px,1fr));gap:12px;margin-bottom:16px}.acceptance-summary{display:grid;gap:4px;padding:16px}.acceptance-summary strong{font-size:2rem;line-height:1}.acceptance-summary.pass{border-left:5px solid #4d7654}.acceptance-summary.review{border-left:5px solid #b8762b}.acceptance-summary.blocked{border-left:5px solid #963f36}.acceptance-check-list{display:grid;gap:14px}.acceptance-area{border:1px solid var(--plotline-line);border-radius:10px;padding:12px;background:rgba(255,255,255,.62)}.acceptance-area h3{margin:0 0 10px;font-size:1.05rem}.acceptance-check-items{display:grid;gap:8px}.acceptance-check-item{display:grid;grid-template-columns:92px minmax(0,1fr);gap:10px;align-items:start;border:1px solid rgba(82,75,65,.12);border-radius:8px;padding:10px;background:rgba(255,255,255,.74)}.acceptance-check-item p{margin:2px 0 0;color:var(--plotline-muted)}.acceptance-status{display:inline-flex;justify-content:center;width:fit-content;min-width:74px;border-radius:999px;padding:3px 9px;font-size:.72rem;font-weight:900;text-transform:uppercase}.acceptance-check-item.pass .acceptance-status{color:#24512b;background:#e6f4e7}.acceptance-check-item.review .acceptance-status{color:#7b4b13;background:#fbecd3}.acceptance-check-item.blocked .acceptance-status{color:#7a2222;background:#fff0f0}.plotline-confirm-modal .modal-title{color:var(--plotline-ink)}.plotline-confirm-modal .modal-body p{white-space:pre-line}.delete-confirm-field{border:1px solid rgba(163,61,61,.22);border-radius:8px;padding:12px;background:rgba(255,247,244,.7)}@media print{header,.breadcrumb-trail,.context-header,.button-row,.story-bible-nav,.inspector-quick-nav{display:none!important}.plotline-shell{max-width:none;padding:0}}@media(max-width:760px){.plotline-shell{padding-left:14px;padding-right:14px}.page-heading{display:block}.page-heading .button-row,.timeline-filter{margin-top:14px}.timeline-filter{align-items:stretch;flex-direction:column}.timeline-navigation-card{grid-template-areas:"copy" "actions";grid-template-columns:1fr}.timeline-navigation-card-icon{display:none}.timeline-navigation-card-actions{justify-content:center}.story-bible-search,.story-bible-section-heading{align-items:stretch;flex-direction:column}.story-bible-scene-summary,.attention-list article{grid-template-columns:1fr}.writer-dashboard-grid{grid-template-columns:1fr}.writer-checklist-row,.writer-add-inline{grid-template-columns:1fr}.trial-status-panel--signup,.trial-status-panel__heading,.trial-dashboard-banner{align-items:stretch;flex-direction:column}.trial-dashboard-banner__actions,.trial-dashboard-banner__actions .btn,.trial-status-panel--signup .btn{width:100%}.attention-list p{grid-column:auto}}@media(max-width:900px){.workspace-layout,.workspace-layout.inspector-drawer-open{grid-template-columns:1fr;gap:14px}.timeline-inspector-resizer{display:none}.scene-inspector-panel{position:static;max-height:none;overflow:visible}.scene-inspector-body{max-height:none;overflow:visible}}@media(max-width:1100px){.metric-graph-row{grid-template-columns:1fr}.health-kpi-grid,.analytics-grid-two,.analytics-grid-three{grid-template-columns:1fr}.analytics-metric-row{grid-template-columns:1fr}.analytics-metric-label{border-right:0}}.floor-plan-list{display:grid;gap:12px}.floor-plan-list-item{align-items:center;border:1px solid var(--border-color,#d8ded9);border-radius:8px;display:flex;justify-content:space-between;gap:16px;padding:14px}.floor-plan-list-item h2{font-size:1.05rem;margin:0 0 4px}.floor-plan-list-item p{margin:0}.floor-plan-tools{display:grid;gap:14px}.floor-plan-meta-wide{max-width:none}.floor-plan-tabs{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:12px}.floor-plan-tab{background:var(--panel-bg,#fff);border:1px solid var(--border-color,#d8ded9);border-radius:999px;color:inherit;padding:6px 12px}.floor-plan-tab.active{background:var(--bs-primary,#2f6f63);border-color:var(--bs-primary,#2f6f63);color:#fff}.floor-plan-layout{display:grid;gap:16px;grid-template-columns:minmax(0,1fr) minmax(320px,360px)}.floor-plan-editor--occupancy .floor-plan-layout{grid-template-columns:minmax(0,1fr)}.floor-plan-editor-toolbar{background:rgba(255,255,255,.92);border:1px solid var(--border-color,#d8ded9);border-radius:8px;display:grid;gap:10px;margin-bottom:12px;padding:10px 12px;position:sticky;top:10px;z-index:20}.floor-plan-toolbar-main,.floor-plan-toolbar-floor-group,.floor-plan-toolbar-control-group,.floor-plan-toolbar-action-group,.floor-plan-occupancy-scene-row{align-items:center;display:flex;flex-wrap:wrap;gap:10px}.floor-plan-toolbar-main{justify-content:space-between}.floor-plan-toolbar-floor-group{flex:1 1 420px;min-width:min(100%,320px)}.floor-plan-active-floor{display:grid;gap:2px}.floor-plan-toolbar-control-group{flex:0 1 auto}.floor-plan-toolbar-action-group{flex:1 1 360px;justify-content:flex-end}.floor-plan-occupancy-scene-row{border-top:1px solid rgba(47,111,99,.12);padding-top:9px}.floor-plan-occupancy-scene-row[hidden]{display:none}.floor-plan-occupancy-scene-row .floor-plan-reference-control{flex:1 1 320px;min-width:min(100%,320px)}.floor-plan-occupancy-scene-row .form-select{width:100%}.floor-plan-occupancy-warning-panel{background:rgba(47,111,99,.05);border:1px solid rgba(47,111,99,.16);border-radius:8px;color:var(--plotline-ink,#1e252b);flex:1 1 100%;font-size:.82rem;padding:.55rem .7rem}.floor-plan-occupancy-warning-panel strong{display:block;font-size:.78rem;margin-bottom:.25rem;text-transform:uppercase}.floor-plan-occupancy-warning-panel p,.floor-plan-occupancy-warning-panel ul{margin:0}.floor-plan-occupancy-warning-panel ul{display:grid;gap:.25rem;list-style:none;padding:0}.floor-plan-occupancy-warning,.floor-plan-occupancy-warning-empty{border-radius:6px;font-weight:700;padding:.32rem .45rem}.floor-plan-occupancy-warning-empty{background:rgba(47,111,99,.08);color:var(--plotline-accent-dark,#22534a)}.floor-plan-occupancy-warning--warning{background:rgba(251,236,211,.78);color:#7b4b12}.floor-plan-occupancy-warning--info{background:rgba(233,243,248,.86);color:#245b78}.floor-plan-occupancy-warning[hidden],.floor-plan-occupancy-warning-empty[hidden]{display:none}.floor-plan-editor-toolbar .muted{display:block;font-size:.76rem;line-height:1.1}.floor-plan-toolbar-check,.floor-plan-reference-control{align-items:center;color:var(--muted-color,#6b756f);display:inline-flex;font-size:.82rem;font-weight:700;gap:6px}.floor-plan-reference-control{align-items:flex-start;flex-direction:column;gap:2px}.floor-plan-reference-control .form-select{min-width:180px}.floor-plan-save-status{border:1px solid rgba(47,111,99,.2);border-radius:999px;color:var(--plotline-accent-dark,#22534a);background:rgba(47,111,99,.08);font-size:.78rem;font-weight:800;padding:4px 9px}.floor-plan-save-status[data-save-state="dirty"]{border-color:rgba(184,118,43,.32);color:#7b4b12;background:rgba(251,236,211,.72)}.floor-plan-save-status[data-save-state="saving"]{border-color:rgba(51,117,155,.3);color:#245b78;background:rgba(233,243,248,.82)}.floor-plan-save-status[data-save-state="failed"]{border-color:rgba(163,61,61,.32);color:#8a3434;background:rgba(255,232,232,.9)}.floor-plan-floor{display:none}.floor-plan-floor.active{display:block}.floor-plan-stage{min-width:0}.floor-plan-grid-wrap{max-width:100%;max-height:calc(100vh - 250px);min-height:min(58vh,520px);overflow:auto;padding-bottom:8px}.floor-plan-grid{--cell-size:34px;background:linear-gradient(to right,rgba(93,111,101,.18) 1px,transparent 1px),linear-gradient(to bottom,rgba(93,111,101,.18) 1px,transparent 1px),var(--panel-bg,#fff);background-size:var(--cell-size) var(--cell-size),var(--cell-size) var(--cell-size),auto;border:1px solid var(--border-color,#d8ded9);border-radius:8px;height:calc(var(--grid-height)*var(--cell-size));min-width:calc(var(--grid-width)*var(--cell-size));position:relative;width:calc(var(--grid-width)*var(--cell-size))}.floor-plan-coordinate-label{color:rgba(33,61,55,.42);font-size:.62rem;font-weight:800;line-height:1;pointer-events:none;position:absolute;text-shadow:0 1px 0 rgba(255,255,255,.7);user-select:none;z-index:5}.floor-plan-coordinate-label--column{left:calc(var(--coord-x)*var(--cell-size) + 4px);top:3px}.floor-plan-coordinate-label--row{left:4px;top:calc(var(--coord-y)*var(--cell-size) + 4px)}.floor-plan-reference-overlay{inset:0;pointer-events:none;position:absolute;z-index:1}.floor-plan-reference-block{align-items:center;background:rgba(47,111,99,.08);border:1px dashed rgba(47,111,99,.34);border-radius:2px;color:rgba(27,55,49,.46);display:flex;font-size:.62rem;font-weight:800;height:calc(var(--h)*var(--cell-size));justify-content:center;left:calc(var(--x)*var(--cell-size));line-height:1.05;overflow:hidden;padding:3px;position:absolute;text-align:center;top:calc(var(--y)*var(--cell-size));width:calc(var(--w)*var(--cell-size))}.floor-plan-reference-warning{background:rgba(251,236,211,.92);border:1px solid rgba(184,118,43,.34);border-radius:999px;color:#7b4b12;font-size:.76rem;font-weight:800;left:10px;padding:4px 10px;pointer-events:none;position:absolute;top:10px;z-index:6}.floor-plan-background-image{height:auto;left:0;max-width:none;opacity:var(--bg-opacity,.35);pointer-events:none;position:absolute;top:0;transform:translate(var(--bg-offset-x,0),var(--bg-offset-y,0)) scale(var(--bg-scale,1));transform-origin:top left;user-select:none;width:100%;z-index:0}.floor-plan-background-image.is-locked{pointer-events:none}.floor-plan-block{align-items:center;--floor-plan-wall-color:rgba(44,84,75,.55);border:2px solid transparent;border-radius:2px;color:#12332c;cursor:grab;display:flex;font-size:.72rem;font-weight:700;height:calc(var(--h)*var(--cell-size));justify-content:center;left:calc(var(--x)*var(--cell-size));line-height:1.08;overflow:hidden;padding:4px;position:absolute;text-align:center;top:calc(var(--y)*var(--cell-size));touch-action:none;width:calc(var(--w)*var(--cell-size));z-index:2}.floor-plan-wall-segment{background:var(--floor-plan-wall-color);pointer-events:none;position:absolute;z-index:2}.floor-plan-wall-segment--north,.floor-plan-wall-segment--south{height:2px;left:var(--wall-start);width:var(--wall-length)}.floor-plan-wall-segment--north{top:0}.floor-plan-wall-segment--south{bottom:0}.floor-plan-wall-segment--east,.floor-plan-wall-segment--west{height:var(--wall-length);top:var(--wall-start);width:2px}.floor-plan-wall-segment--east{right:0}.floor-plan-wall-segment--west{left:0}.floor-plan-block-label{display:-webkit-box;max-width:100%;overflow:hidden;overflow-wrap:normal;text-overflow:ellipsis;-webkit-box-orient:vertical;-webkit-line-clamp:1}.floor-plan-block[style*="--h:2"] .floor-plan-block-label,.floor-plan-block[style*="--h:3"] .floor-plan-block-label,.floor-plan-block[style*="--h:4"] .floor-plan-block-label,.floor-plan-block[style*="--h:5"] .floor-plan-block-label,.floor-plan-block[style*="--h:6"] .floor-plan-block-label,.floor-plan-block[style*="--h:7"] .floor-plan-block-label,.floor-plan-block[style*="--h:8"] .floor-plan-block-label{-webkit-line-clamp:2}.floor-plan-block.selected{box-shadow:0 0 0 3px rgba(47,111,99,.28);outline:2px solid var(--bs-primary,#2f6f63);z-index:3}.floor-plan-block.overlap{border-color:#b45544;box-shadow:inset 0 0 0 2px rgba(180,85,68,.18)}.floor-plan-block.is-hidden-location{background-image:repeating-linear-gradient(135deg,rgba(18,51,44,.08) 0,rgba(18,51,44,.08) 3px,transparent 3px,transparent 9px);box-shadow:inset 0 0 0 1px rgba(43,54,49,.18)}.floor-plan-block.is-hidden-location.selected{box-shadow:inset 0 0 0 1px rgba(43,54,49,.18),0 0 0 3px rgba(47,111,99,.28)}.floor-plan-block.is-hidden-location.overlap{box-shadow:inset 0 0 0 2px rgba(180,85,68,.18),inset 0 0 0 1px rgba(43,54,49,.18)}.floor-plan-secret-route{border-top:2px dashed rgba(69,55,42,.58);height:0;left:calc(var(--route-x,0)*var(--cell-size));opacity:.72;pointer-events:none;position:absolute;top:calc(var(--route-y,0)*var(--cell-size));transform:rotate(var(--route-angle,0));transform-origin:0 50%;width:calc(var(--route-length,0)*var(--cell-size));z-index:3}.floor-plan-secret-route::after{background:rgba(255,250,242,.9);border:1px solid rgba(69,55,42,.5);border-radius:50%;content:"";height:7px;left:50%;position:absolute;top:-5px;transform:translateX(-50%);width:7px}.floor-plan-transition-marker{align-items:center;--transition-marker-ink:#12332c;--transition-marker-window:#246f9f;--transition-marker-blocked:#9b342b;background:rgba(255,250,242,.98);border:1px solid rgba(47,111,99,.55);border-radius:50%;box-shadow:0 2px 6px rgba(31,37,34,.16);color:var(--transition-marker-ink);display:flex;font-size:.72rem;font-weight:900;height:21px;justify-content:center;left:calc(var(--transition-x,0)*var(--cell-size));line-height:1;pointer-events:none;position:absolute;top:calc(var(--transition-y,0)*var(--cell-size));transform:translate(-50%,-50%);width:21px;z-index:4}.floor-plan-transition-marker svg{display:block;height:21px;overflow:visible;width:21px}.floor-plan-transition-marker.is-vertical svg{transform:rotate(90deg)}.floor-plan-transition-marker .marker-line,.floor-plan-transition-marker .marker-arc,.floor-plan-transition-marker .marker-window,.floor-plan-transition-marker .marker-blocked{fill:none;stroke:currentColor;stroke-linecap:round;stroke-linejoin:round;stroke-width:1.7}.floor-plan-transition-marker .marker-arc{stroke-width:1.35}.floor-plan-transition-marker .marker-window{stroke:var(--transition-marker-window)}.floor-plan-transition-marker .marker-dotted{opacity:.72;stroke-dasharray:1.4 2}.floor-plan-transition-marker .marker-blocked{stroke:var(--transition-marker-blocked);stroke-width:1.8}.floor-plan-transition-marker .marker-strong{stroke-width:2}.floor-plan-transition-marker .marker-track{opacity:.72}.floor-plan-transition-marker--window{background:rgba(239,249,255,.98);border-color:rgba(36,111,159,.48)}.floor-plan-transition-marker--sliding-door{background:rgba(248,252,249,.98);border-color:rgba(47,111,99,.58)}.floor-plan-transition-marker--french-door{background:rgba(255,252,246,.98);border-color:rgba(119,86,45,.5)}.floor-plan-transition-marker--secret-door{background:rgba(255,250,242,.88);border-style:dashed}.floor-plan-transition-marker--ladder{background:rgba(246,248,245,.98);border-color:rgba(77,91,67,.55)}.floor-plan-transition-marker--blocked-door{background:rgba(255,244,241,.98);border-color:rgba(155,52,43,.52)}.floor-plan-transition-marker--exterior-door{border-width:2px}.floor-plan-transition-marker.is-shared-edge{background:rgba(255,255,255,.98);border-color:rgba(47,111,99,.72)}.floor-plan-transition-marker--window.is-shared-edge{background:rgba(239,249,255,.98);border-color:rgba(36,111,159,.58)}.floor-plan-transition-marker--blocked-door.is-shared-edge{background:rgba(255,244,241,.98);border-color:rgba(155,52,43,.6)}.visual-card-heading{align-items:flex-start;display:flex;gap:12px}.visual-card-heading>div{min-width:0}.visual-avatar{align-items:center;aspect-ratio:1;background:linear-gradient(135deg,rgba(47,111,99,.16),rgba(212,154,98,.16));border:1px solid rgba(47,111,99,.22);border-radius:999px;color:var(--plotline-accent-dark,#22534a);display:inline-flex;flex:0 0 auto;font-weight:900;justify-content:center;letter-spacing:.02em;overflow:hidden;text-transform:uppercase}.visual-avatar img{height:100%;object-fit:cover;width:100%}.visual-avatar--sm{font-size:.72rem;width:32px}.visual-avatar--md{font-size:.9rem;width:48px}.visual-avatar--lg{font-size:1.3rem;width:96px}.visual-avatar--xl{font-size:1.6rem;width:128px}.visual-image-editor{align-items:center;background:rgba(47,111,99,.05);border:1px solid rgba(47,111,99,.14);border-radius:8px;display:flex;gap:18px;padding:14px}.visual-image-editor__controls{flex:1 1 auto;min-width:220px}.floor-plan-block--room{background:#d9eee7}.floor-plan-block--corridor{background:#e7e2f4}.floor-plan-block--openspace{background:#e5efd4}.floor-plan-block--exterior{background:#d9ecf3}.floor-plan-block--other{background:#ece9e1}.floor-plan-resize-handle{border-bottom:10px solid rgba(18,51,44,.45);border-left:10px solid transparent;bottom:4px;height:0;position:absolute;right:4px;width:0}.floor-plan-side-panel{align-self:start;position:sticky;top:82px}.floor-plan-side-panel h2{font-size:1.05rem;margin-bottom:8px}.floor-plan-side-panel h3{font-size:.92rem;margin:0 0 8px}.floor-plan-toolbox{background:var(--panel-bg,#fff);border:1px solid var(--border-color,#d8ded9);border-radius:8px;display:grid;grid-template-rows:auto minmax(0,1fr);max-height:calc(100vh - 250px);min-height:min(58vh,520px);overflow:hidden}.floor-plan-toolbox-tabs{border-bottom:1px solid var(--border-color,#d8ded9);display:flex;flex-wrap:wrap;gap:0}.floor-plan-toolbox-tab{background:transparent;border:0;border-right:1px solid var(--border-color,#d8ded9);border-bottom:1px solid var(--border-color,#d8ded9);color:inherit;flex:1 1 118px;font-size:.82rem;font-weight:800;min-width:112px;padding:10px 8px}.floor-plan-toolbox-tab:last-child,.floor-plan-toolbox-tab.active:last-child{border-right:0}.floor-plan-toolbox-tab.active{background:rgba(47,111,99,.1);border-bottom-color:var(--plotline-accent,#2f6f63);color:var(--plotline-accent-dark,#22534a)}.floor-plan-toolbox-body{min-height:0;overflow:auto}.floor-plan-tool-card{background:var(--panel-bg,#fff);border:1px solid var(--border-color,#d8ded9);border-radius:8px;padding:14px}.floor-plan-toolbox .floor-plan-tool-card{background:transparent;border:0;border-radius:0}.floor-plan-tool-card[hidden]{display:none}.floor-plan-tool-card p{margin-bottom:10px}.floor-plan-tool-subsection{border-top:1px solid var(--border-color,#d8ded9);margin-top:12px;padding-top:12px}.floor-plan-tool-subsection:first-of-type{border-top:0;margin-top:0;padding-top:0}.floor-plan-background-file{border:1px solid rgba(47,111,99,.16);border-radius:6px;font-size:.86rem;padding:8px 10px}.floor-plan-background-range{align-items:center;display:grid;gap:10px;grid-template-columns:minmax(0,1fr) 44px}.floor-plan-background-range span{color:var(--muted-text,#5d6f65);font-size:.8rem;font-variant-numeric:tabular-nums;text-align:right}.floor-plan-transition-list{display:grid;gap:8px}.floor-plan-transition-item{border:1px solid rgba(47,111,99,.14);border-radius:6px;display:grid;gap:8px;padding:8px}.floor-plan-transition-item strong,.floor-plan-transition-item span{display:block;font-size:.84rem}.floor-plan-transition-item span{color:var(--muted-text,#5d6f65)}.scene-occupancy-form{display:grid;gap:.5rem}.scene-occupancy-status{justify-self:start;border-radius:999px;padding:.2rem .55rem;color:var(--plotline-muted);background:var(--plotline-soft);font-size:.78rem;font-weight:700}.scene-occupancy-status[data-save-state="saving"]{color:#7a4d08;background:#fff4d6}.scene-occupancy-status[data-save-state="failed"]{color:#842029;background:#f8d7da}.scene-occupancy-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:1rem}.scene-occupancy-grid h4{margin:0 0 .5rem;font-size:.95rem}.scene-occupancy-row{display:grid;grid-template-columns:minmax(8rem,.45fr) minmax(0,.55fr);align-items:center;gap:.5rem;margin-bottom:.45rem}.floor-plan-editor--occupancy .floor-plan-block{cursor:default;touch-action:auto}.floor-plan-editor--occupancy .floor-plan-resize-handle{display:none}.floor-plan-editor--occupancy .floor-plan-side-panel{display:none}.floor-plan-occupancy-tray{position:absolute;z-index:14;height:calc(var(--h)*var(--cell-size));left:calc(var(--x)*var(--cell-size));top:calc(var(--y)*var(--cell-size));width:calc(var(--w)*var(--cell-size));display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:.18rem;padding:0 0 .25rem;pointer-events:auto}.floor-plan-occupancy-tray[hidden]{display:none}.floor-plan-occupancy-token{display:grid;place-items:center;width:1.8rem;height:1.8rem;overflow:hidden;border:2px solid #fff;border-radius:999px;color:#fff;background:var(--plotline-accent);box-shadow:0 4px 12px rgba(30,37,43,.18);font-size:.68rem;font-weight:800}.floor-plan-occupancy-token img{width:100%;height:100%;object-fit:cover}.floor-plan-occupancy-token--asset{width:1.45rem;height:1.45rem;background:#805c15;font-size:.58rem}.floor-plan-occupancy-more{border-radius:999px;padding:.15rem .36rem;color:var(--plotline-ink);background:rgba(255,255,255,.92);box-shadow:0 4px 12px rgba(30,37,43,.12);font-size:.72rem;font-weight:800}.floor-plan-occupancy-message{align-self:start;background:rgba(255,255,255,.94);border:1px solid rgba(47,111,99,.18);border-radius:8px;box-shadow:0 6px 16px rgba(30,37,43,.08);color:var(--muted-color,#6b756f);font-size:.82rem;font-weight:700;grid-column:1/-1;grid-row:1;justify-self:center;margin-top:.55rem;max-width:min(92%,520px);padding:.45rem .7rem;position:relative;z-index:16}.floor-plan-occupancy-message[hidden]{display:none}.floor-plan-transition-accordion .accordion-item{background:transparent;border-color:var(--border-color,#d8ded9)}.floor-plan-transition-accordion .accordion-button{background:rgba(47,111,99,.06);color:inherit;font-size:.88rem;font-weight:800;padding:10px 12px}.floor-plan-transition-accordion .accordion-button:not(.collapsed){background:rgba(47,111,99,.12);color:var(--plotline-accent-dark,#22534a);box-shadow:inset 0 -1px 0 var(--border-color,#d8ded9)}.floor-plan-transition-accordion .accordion-body{padding:12px}.floor-plan-checkbox{align-items:center;display:inline-flex;gap:6px;font-weight:700;margin-bottom:4px}.floor-plan-choice-row{display:grid;gap:4px;margin-bottom:10px}.floor-plan-choice-row label{align-items:center;display:flex;gap:6px;font-size:.88rem}.floor-plan-overlap-warning{background:rgba(180,85,68,.12);border:1px solid rgba(180,85,68,.35);border-radius:6px;color:#8f3f31;margin-bottom:10px;padding:8px 10px}[data-bs-theme="dark"] .floor-plan-grid,.dark .floor-plan-grid{background:linear-gradient(to right,rgba(214,224,218,.12) 1px,transparent 1px),linear-gradient(to bottom,rgba(214,224,218,.12) 1px,transparent 1px),#15201d;background-size:var(--cell-size) var(--cell-size),var(--cell-size) var(--cell-size),auto}[data-bs-theme="dark"] .floor-plan-editor-toolbar,.dark .floor-plan-editor-toolbar,[data-bs-theme="dark"] .floor-plan-toolbox,.dark .floor-plan-toolbox,[data-bs-theme="dark"] .floor-plan-tool-card,.dark .floor-plan-tool-card{background:var(--panel-bg,#1f2522)}[data-bs-theme="dark"] .floor-plan-toolbox .floor-plan-tool-card,.dark .floor-plan-toolbox .floor-plan-tool-card{background:transparent}[data-bs-theme="dark"] .floor-plan-toolbox-tab.active,.dark .floor-plan-toolbox-tab.active{background:rgba(212,154,98,.16);color:var(--plotline-accent-dark,#f0c99d)}[data-bs-theme="dark"] .floor-plan-block,.dark .floor-plan-block{--floor-plan-wall-color:rgba(212,154,98,.6);color:#f1f6f3}[data-bs-theme="dark"] .floor-plan-block.is-hidden-location,.dark .floor-plan-block.is-hidden-location{background-image:repeating-linear-gradient(135deg,rgba(244,234,220,.09) 0,rgba(244,234,220,.09) 3px,transparent 3px,transparent 9px);box-shadow:inset 0 0 0 1px rgba(244,234,220,.2)}[data-bs-theme="dark"] .floor-plan-secret-route,.dark .floor-plan-secret-route{border-top-color:rgba(244,204,160,.58);opacity:.76}[data-bs-theme="dark"] .floor-plan-secret-route::after,.dark .floor-plan-secret-route::after{background:rgba(42,35,30,.95);border-color:rgba(244,204,160,.55)}[data-bs-theme="dark"] .floor-plan-coordinate-label,.dark .floor-plan-coordinate-label{color:rgba(244,234,220,.46);text-shadow:0 1px 0 rgba(0,0,0,.55)}[data-bs-theme="dark"] .floor-plan-reference-block,.dark .floor-plan-reference-block{background:rgba(131,199,242,.08);border-color:rgba(131,199,242,.32);color:rgba(244,234,220,.46)}[data-bs-theme="dark"] .floor-plan-reference-warning,.dark .floor-plan-reference-warning{background:rgba(84,57,25,.92);border-color:rgba(244,177,100,.32);color:#ffd9a5}[data-bs-theme="dark"] .floor-plan-transition-marker,.dark .floor-plan-transition-marker{--transition-marker-ink:#f4eadc;--transition-marker-window:#83c7f2;--transition-marker-blocked:#f08a78;background:rgba(42,35,30,.98);border-color:rgba(212,154,98,.6)}[data-bs-theme="dark"] .floor-plan-transition-marker.is-shared-edge,.dark .floor-plan-transition-marker.is-shared-edge{background:rgba(48,39,32,.98);border-color:rgba(212,154,98,.78)}[data-bs-theme="dark"] .floor-plan-transition-marker--window,.dark .floor-plan-transition-marker--window,[data-bs-theme="dark"] .floor-plan-transition-marker--window.is-shared-edge,.dark .floor-plan-transition-marker--window.is-shared-edge{background:rgba(24,45,58,.98);border-color:rgba(131,199,242,.66)}[data-bs-theme="dark"] .floor-plan-transition-marker--sliding-door,.dark .floor-plan-transition-marker--sliding-door,[data-bs-theme="dark"] .floor-plan-transition-marker--french-door,.dark .floor-plan-transition-marker--french-door,[data-bs-theme="dark"] .floor-plan-transition-marker--ladder,.dark .floor-plan-transition-marker--ladder{background:rgba(39,43,37,.98);border-color:rgba(212,154,98,.58)}[data-bs-theme="dark"] .floor-plan-transition-marker--blocked-door,.dark .floor-plan-transition-marker--blocked-door,[data-bs-theme="dark"] .floor-plan-transition-marker--blocked-door.is-shared-edge,.dark .floor-plan-transition-marker--blocked-door.is-shared-edge{background:rgba(58,33,28,.98);border-color:rgba(240,138,120,.66)}[data-bs-theme="dark"] .visual-avatar,.dark .visual-avatar{background:linear-gradient(135deg,rgba(131,199,242,.14),rgba(212,154,98,.18));border-color:rgba(244,234,220,.18);color:#f4eadc}[data-bs-theme="dark"] .visual-image-editor,.dark .visual-image-editor{background:rgba(244,234,220,.04);border-color:rgba(244,234,220,.12)}[data-bs-theme="dark"] .floor-plan-transition-item,.dark .floor-plan-transition-item{border-color:rgba(212,154,98,.22)}[data-bs-theme="dark"] .scene-occupancy-status,.dark .scene-occupancy-status{color:#d9c8b8;background:rgba(212,154,98,.12)}[data-bs-theme="dark"] .floor-plan-occupancy-token,.dark .floor-plan-occupancy-token{border-color:#1f2630;box-shadow:0 4px 12px rgba(0,0,0,.28)}[data-bs-theme="dark"] .floor-plan-occupancy-more,.dark .floor-plan-occupancy-more{color:#f1e7dd;background:rgba(31,38,48,.92)}[data-bs-theme="dark"] .floor-plan-occupancy-message,.dark .floor-plan-occupancy-message{background:rgba(31,38,48,.94);border-color:rgba(212,154,98,.24);color:#d9c8b8}[data-bs-theme="dark"] .floor-plan-occupancy-warning-panel,.dark .floor-plan-occupancy-warning-panel{background:rgba(244,234,220,.04);border-color:rgba(212,154,98,.2);color:#f1e7dd}[data-bs-theme="dark"] .floor-plan-occupancy-warning-empty,.dark .floor-plan-occupancy-warning-empty{background:rgba(47,111,99,.18);color:#b8e2d7}[data-bs-theme="dark"] .floor-plan-occupancy-warning--warning,.dark .floor-plan-occupancy-warning--warning{background:rgba(84,57,25,.92);color:#ffd9a5}[data-bs-theme="dark"] .floor-plan-occupancy-warning--info,.dark .floor-plan-occupancy-warning--info{background:rgba(24,45,58,.92);color:#b9dcf3}[data-bs-theme="dark"] .floor-plan-transition-accordion .accordion-item,.dark .floor-plan-transition-accordion .accordion-item{border-color:rgba(212,154,98,.22)}[data-bs-theme="dark"] .floor-plan-transition-accordion .accordion-button,.dark .floor-plan-transition-accordion .accordion-button{background:rgba(212,154,98,.08);color:#f4eadc}[data-bs-theme="dark"] .floor-plan-transition-accordion .accordion-button:not(.collapsed),.dark .floor-plan-transition-accordion .accordion-button:not(.collapsed){background:rgba(212,154,98,.16);color:var(--plotline-accent-dark,#f0c99d);box-shadow:inset 0 -1px 0 rgba(212,154,98,.22)}[data-bs-theme="dark"] .floor-plan-block--room,.dark .floor-plan-block--room{background:#29584f}[data-bs-theme="dark"] .floor-plan-block--corridor,.dark .floor-plan-block--corridor{background:#514876}[data-bs-theme="dark"] .floor-plan-block--openspace,.dark .floor-plan-block--openspace{background:#4f6133}[data-bs-theme="dark"] .floor-plan-block--exterior,.dark .floor-plan-block--exterior{background:#315d6f}[data-bs-theme="dark"] .floor-plan-block--other,.dark .floor-plan-block--other{background:#5b564c}@media(max-width:1100px){.floor-plan-layout,.floor-plan-editor-toolbar{grid-template-columns:1fr}.floor-plan-grid-wrap{max-height:62vh}.floor-plan-side-panel{position:static}.floor-plan-toolbox{max-height:none}} \ No newline at end of file +html{font-size:15px;min-height:100%}@media(min-width:768px){html{font-size:16px}}:root{--plotline-ink:#1e252b;--plotline-muted:#66717b;--plotline-paper:#fbfaf7;--plotline-panel:#fff;--plotline-line:#d8ddd8;--plotline-accent:#2f6f63;--plotline-accent-dark:#22534a;--plotline-soft:#eef5f2;--timeline-label-width:180px;--timeline-scene-width:220px;--timeline-grid-gap:10px}body{min-height:100%;margin-bottom:0;color:var(--plotline-ink);background:var(--plotline-paper)}a{color:var(--plotline-accent-dark)}.btn-primary{--bs-btn-bg:var(--plotline-accent);--bs-btn-border-color:var(--plotline-accent);--bs-btn-hover-bg:var(--plotline-accent-dark);--bs-btn-hover-border-color:var(--plotline-accent-dark)}.btn-outline-primary{--bs-btn-color:var(--plotline-accent-dark);--bs-btn-border-color:var(--plotline-accent);--bs-btn-hover-bg:var(--plotline-accent);--bs-btn-hover-border-color:var(--plotline-accent)}.plotline-nav{background:rgba(255,255,255,.94);backdrop-filter:blur(8px)}.plotline-shell{max-width:1480px;padding-left:24px;padding-right:24px}.plotline-shell-wide{max-width:none;padding-left:clamp(18px,2vw,32px);padding-right:clamp(18px,2vw,32px)}.page-heading{display:flex;align-items:flex-start;justify-content:space-between;gap:24px;margin:18px 0 24px}.workspace-heading{display:flex;align-items:flex-end;justify-content:space-between;gap:18px;margin:14px 0 18px}.workspace-heading h1{margin:0;font-size:clamp(1.8rem,3vw,2.7rem);line-height:1.05}.page-heading.compact{max-width:980px}.page-heading h1{margin:0;font-size:clamp(2rem,4vw,3.2rem);line-height:1.05;letter-spacing:0}.eyebrow{margin:0 0 6px;color:var(--plotline-accent-dark);font-size:.78rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase}.lead-text{max-width:760px;margin:10px 0 0;color:var(--plotline-muted);font-size:1.05rem}.button-row{display:flex;flex-wrap:wrap;align-items:center;gap:8px}.button-row form,.compact-buttons form,.asset-card-footer form,td.text-end form,form[data-confirm-message]{display:inline-flex;align-items:center;margin:0}td.text-end{white-space:nowrap}.content-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:16px}.plain-card,.empty-panel,.edit-panel,.list-section{background:var(--plotline-panel);border:1px solid var(--plotline-line);border-radius:8px;padding:20px;box-shadow:0 10px 24px rgba(30,37,43,.04)}.plain-card h2,.empty-panel h2,.list-section h2{margin-top:0;font-size:1.35rem}.plain-card p,.empty-panel p,.muted{color:var(--plotline-muted)}.edit-panel{max-width:980px}.feature-request-admin-page .page-heading.compact,.feature-request-admin-page .edit-panel{max-width:none}.feature-request-admin-table{table-layout:fixed}.feature-request-admin-table th,.feature-request-admin-table td{vertical-align:middle}.feature-request-admin-table__preview{max-width:180px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.feature-request-admin-table__action{width:78px}@media(max-width:1100px){.feature-request-admin-table{table-layout:auto}.feature-request-admin-table__preview{max-width:160px}}.trial-status-panel,.trial-dashboard-banner{border:1px solid var(--plotline-line);border-radius:8px;padding:18px 20px;background:var(--plotline-panel)}.trial-status-panel{display:grid;gap:12px;margin-bottom:18px}.trial-status-panel--signup{grid-template-columns:minmax(0,1fr) auto;align-items:center;max-width:980px}.trial-status-panel h2,.trial-status-panel h3,.trial-dashboard-banner h2{margin:0}.trial-status-panel p,.trial-dashboard-banner p{margin-bottom:0}.trial-status-panel__heading,.trial-dashboard-banner{display:flex;gap:16px;align-items:center;justify-content:space-between}.trial-dashboard-banner{margin-bottom:18px}.trial-dashboard-banner__body{min-width:0}.trial-dashboard-banner__actions{display:flex;flex:0 0 auto;flex-wrap:wrap;gap:8px}.trial-progress{height:10px;overflow:hidden;border-radius:999px;background:rgba(84,68,48,.12)}.trial-progress__bar{height:100%;border-radius:inherit}.trial-status-panel[hidden],.trial-dashboard-banner[hidden]{display:none}.location-page .page-heading.compact,.location-page .edit-panel,.location-page .empty-panel,.location-page .drag-drop-panel{max-width:none}.import-panel,.import-preview-section{max-width:none}.import-json-input{font-family:Consolas,"Liberation Mono",Menlo,monospace;font-size:.88rem;line-height:1.45;min-height:34rem;max-height:64vh;overflow:auto;resize:vertical;white-space:pre}.import-preview-heading,.import-counts{display:flex;align-items:flex-start;gap:12px}.import-preview-heading{justify-content:space-between;margin-bottom:16px}.import-counts{flex-wrap:wrap}.import-counts span{display:inline-flex;align-items:baseline;gap:5px;border:1px solid var(--plotline-line);border-radius:999px;padding:5px 11px;background:var(--plotline-soft);color:var(--plotline-muted);font-weight:700}.import-counts strong{color:var(--plotline-ink)}.import-tree{display:grid;gap:12px}.import-tree-book{border:1px solid var(--plotline-line);border-radius:8px;padding:14px;background:rgba(255,255,255,.54)}.import-tree-book>summary,.import-tree-chapter>summary{display:flex;align-items:center;justify-content:space-between;gap:12px;cursor:pointer}.import-tree-book>summary span,.import-tree-chapter>summary span{color:var(--plotline-muted);font-size:.84rem;font-weight:700;white-space:nowrap}.import-tree-book h3{margin:0 0 10px;font-size:1.08rem}.import-tree-chapter{border-top:1px solid var(--plotline-line);padding:10px 0 0;margin-top:10px}.import-tree-chapter ul{margin:8px 0 0;color:var(--plotline-muted)}.import-scene-meta{display:block;margin-top:2px;color:var(--plotline-muted);font-size:.82rem}.import-mapping-summary{display:grid;gap:6px;border:1px solid rgba(184,118,43,.28);border-radius:8px;padding:10px 12px;margin-bottom:14px;background:rgba(251,236,211,.5);color:var(--plotline-muted);font-size:.9rem}.import-duplicate-confirm{border:1px solid rgba(184,118,43,.34);border-radius:8px;padding:12px 12px 12px 38px;background:rgba(251,236,211,.72)}.import-confirmation,.import-docs details{border:1px solid var(--plotline-line);border-radius:8px;padding:16px;background:rgba(255,255,255,.42)}.import-confirmation h3,.import-doc-grid h3{margin-top:0;font-size:1.05rem}.import-docs summary{cursor:pointer;font-weight:800}.import-doc-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:14px;margin-top:14px}.import-message-list ul{max-height:16rem;overflow:auto}.scene-editor{max-width:1180px}.table{margin-bottom:0}.table th{color:var(--plotline-muted);font-size:.78rem;letter-spacing:.06em;text-transform:uppercase}.narrow{width:90px;white-space:nowrap}.status-pill{display:inline-flex;align-items:center;width:fit-content;border:1px solid #c8d8d2;border-radius:999px;padding:2px 8px;color:var(--plotline-accent-dark);background:var(--plotline-soft);font-size:.78rem;font-weight:700;white-space:nowrap}.dashboard-summary-card{border-color:var(--plotline-line)}.dashboard-summary-body{padding:10px 12px}.dashboard-summary-label{margin-bottom:4px;font-size:.7rem;line-height:1.15}.dashboard-summary-value{display:block;font-size:1.45rem;line-height:1}.dashboard-summary-calm{border-color:rgba(47,111,99,.28);background:rgba(238,245,242,.62)}.dashboard-summary-mild{border-color:rgba(197,139,43,.32);background:rgba(255,248,232,.68)}.dashboard-summary-attention{border-color:rgba(142,80,103,.32);background:rgba(252,241,246,.7)}.dashboard-progress-card{border-color:rgba(47,111,99,.18);background:linear-gradient(180deg,#fff 0%,rgba(238,245,242,.64) 100%)}.dashboard-progress-body{padding:12px 14px}.dashboard-progress-heading{margin-bottom:8px}.dashboard-progress-title{margin:0 0 2px;font-size:1.05rem;line-height:1.2}.dashboard-series-progress{height:7px;background:rgba(47,111,99,.1)}.dashboard-series-progress .progress-bar{background:linear-gradient(90deg,var(--plotline-accent),#6fa99b)}.dashboard-progress-source{border-color:rgba(47,111,99,.2);color:var(--plotline-accent-dark);background:rgba(238,245,242,.9)}.dashboard-book-title-block h3{line-height:1.16}.dashboard-book-title-block a{color:var(--plotline-ink);text-decoration-color:rgba(47,111,99,.35)}.dashboard-book-subtitle{color:var(--plotline-muted);font-size:.95rem;line-height:1.25}.dashboard-status-pill{border-color:var(--dashboard-status-border,#c8d8d2);color:var(--dashboard-status-ink,var(--plotline-accent-dark));background:var(--dashboard-status-bg,var(--plotline-soft))}.dashboard-status-published{--dashboard-status-border:rgba(47,111,99,.32);--dashboard-status-bg:#e7f2ed;--dashboard-status-ink:#22534a}.dashboard-status-drafting{--dashboard-status-border:rgba(184,118,43,.35);--dashboard-status-bg:#fff2dd;--dashboard-status-ink:#7b4b12}.dashboard-status-planning{--dashboard-status-border:rgba(51,117,155,.3);--dashboard-status-bg:#e9f3f8;--dashboard-status-ink:#245b78}.dashboard-status-research,.dashboard-status-outlining{--dashboard-status-border:rgba(103,80,164,.26);--dashboard-status-bg:#f0edf8;--dashboard-status-ink:#51417c}.dashboard-status-revising{--dashboard-status-border:rgba(123,82,148,.3);--dashboard-status-bg:#f4eefa;--dashboard-status-ink:#5f3e73}.dashboard-status-editing{--dashboard-status-border:rgba(68,75,130,.3);--dashboard-status-bg:#eceef8;--dashboard-status-ink:#343b72}.dashboard-status-proofreading{--dashboard-status-border:rgba(43,130,123,.3);--dashboard-status-bg:#e6f5f2;--dashboard-status-ink:#23625d}.dashboard-status-ready{--dashboard-status-border:rgba(185,142,30,.34);--dashboard-status-bg:#fff6d8;--dashboard-status-ink:#765a0f}.dashboard-status-paused{--dashboard-status-border:rgba(102,113,123,.28);--dashboard-status-bg:#f0f2f1;--dashboard-status-ink:#56616b}.dashboard-status-archived{--dashboard-status-border:rgba(139,80,86,.28);--dashboard-status-bg:#f3eded;--dashboard-status-ink:#76474d}.dashboard-attention-soft{border-color:rgba(102,113,123,.24);color:#56616b;background:#f3f4f2}.word-companion-follow-toggle[aria-pressed="true"]{border-color:rgba(47,111,99,.36);color:var(--plotline-accent-dark);background:var(--plotline-soft);font-weight:700}.word-companion-follow-toggle[aria-pressed="true"]::after{content:" On"}.word-companion-follow-toggle[aria-pressed="false"]::after{content:" Off"}.order-buttons{display:flex;gap:6px}.purpose-list{display:grid;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));gap:8px;max-height:260px;overflow:auto;padding:10px;border:1px solid var(--plotline-line);border-radius:8px;background:#fcfcfb}.purpose-check{display:flex;align-items:center;gap:8px;font-size:.92rem}.timeline-filter{display:flex;align-items:center;gap:8px;min-width:min(420px,100%)}.workspace-layout{display:grid;grid-template-columns:minmax(0,1fr);gap:0;align-items:start;--timeline-inspector-width:min(40vw,560px)}.workspace-layout.inspector-drawer-open{grid-template-columns:minmax(420px,1fr) 10px minmax(420px,var(--timeline-inspector-width));gap:12px}.timeline-workspace{min-width:0;max-width:100%}.timeline-inspector-resizer{position:sticky;top:76px;z-index:25;width:10px;height:calc(100vh - 96px);border-radius:999px;cursor:col-resize;background:linear-gradient(180deg,rgba(47,111,99,.16),rgba(47,111,99,.04))}.timeline-inspector-resizer::before{content:"";display:block;width:2px;height:48px;margin:18px auto;border-radius:999px;background:var(--plotline-accent);opacity:.55}.timeline-inspector-resizer:hover,.timeline-inspector-resizer:focus-visible{background:rgba(47,111,99,.16)}body.timeline-inspector-resizing{cursor:col-resize;user-select:none}.pacing-panel{margin-top:14px;margin-bottom:0;border:1px solid var(--plotline-line);border-radius:8px;padding:14px;background:#fff;box-shadow:0 10px 24px rgba(30,37,43,.04)}.pacing-heading{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;margin-bottom:10px}.pacing-heading h2{margin:0;font-size:1.1rem}.metric-graph-stack{display:grid;gap:10px;max-width:100%;overflow-x:auto;overflow-y:hidden;overscroll-behavior-x:contain;padding-bottom:4px}.metric-graph-row{display:grid;grid-template-columns:150px minmax(260px,1fr);gap:10px;align-items:center;min-width:max(100%,calc(150px + (var(--scene-count,1)*34px)))}.metric-graph-label{color:var(--plotline-muted);font-size:.84rem;font-weight:700}.metric-graph-points{display:grid;grid-template-columns:repeat(var(--scene-count),minmax(28px,1fr));gap:5px;align-items:end;min-height:52px;border-radius:8px;padding:6px;background:linear-gradient(180deg,#f6faf8 0%,#edf4f1 100%);min-width:calc(var(--scene-count)*34px)}.metric-point{display:flex;align-items:flex-end;justify-content:center;height:48px;min-width:28px;color:var(--plotline-accent-dark);text-decoration:none}.metric-point::before{content:"";display:block;width:100%;height:max(8px,var(--metric-height));border-radius:5px 5px 2px 2px;background:linear-gradient(180deg,#6fa99b,var(--plotline-accent-dark));box-shadow:inset 0 1px 0 rgba(255,255,255,.35)}.metric-point span{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0)}.timeline-shell{overflow-x:auto;padding:16px;border:1px solid var(--plotline-line);border-radius:8px;background:linear-gradient(180deg,#fff 0%,#f7faf8 100%)}.workspace-timeline{min-height:420px}.timeline-series-row{display:grid;grid-template-columns:var(--timeline-label-width) max-content;gap:var(--timeline-grid-gap);align-items:stretch;width:max-content;min-width:100%}.timeline-project-title{position:sticky;left:0;z-index:20;display:grid;align-content:start;gap:4px;width:var(--timeline-label-width);min-height:100%;border-radius:8px;padding:12px;color:#fff;background:var(--plotline-accent-dark);font-weight:700;box-shadow:8px 0 18px rgba(30,37,43,.08)}.timeline-project-title span,.timeline-book-title span{color:rgba(255,255,255,.78);font-size:.72rem;letter-spacing:.08em;text-transform:uppercase}.timeline-project-title strong,.timeline-book-title strong{line-height:1.15}.timeline-books{display:flex;gap:var(--timeline-grid-gap);align-items:stretch}.timeline-book{flex:0 0 auto;width:calc((var(--book-scene-count)*var(--timeline-scene-width)) + ((var(--book-scene-count) - 1)*var(--timeline-grid-gap)));min-width:var(--timeline-scene-width)}.timeline-book-title{display:grid;gap:2px;margin-bottom:var(--timeline-grid-gap);border-radius:8px;padding:10px 12px;color:#fff;background:var(--plotline-accent-dark);font-weight:700}.timeline-chapters{display:flex;gap:var(--timeline-grid-gap);align-items:flex-start}.timeline-chapter{flex:0 0 auto;width:calc((var(--chapter-scene-count)*var(--timeline-scene-width)) + ((var(--chapter-scene-count) - 1)*var(--timeline-grid-gap)));min-width:var(--timeline-scene-width);box-sizing:border-box;border-radius:8px;background:rgba(238,245,242,.7);outline:1px solid #d4ded8;outline-offset:0;overflow:visible}.timeline-chapter-title{display:grid;gap:2px;border-bottom:1px solid #d4ded8;padding:10px 12px;color:var(--plotline-accent-dark);font-weight:700}.timeline-chapter-title span{color:var(--plotline-muted);font-size:.76rem;text-transform:uppercase}.timeline-scenes{display:grid;grid-template-columns:repeat(var(--chapter-scene-count),minmax(0,1fr));gap:var(--timeline-grid-gap);width:100%;box-sizing:border-box;min-height:190px;padding:0}.timeline-scene-card,.timeline-empty-scene{display:flex;flex-direction:column;gap:6px;width:100%;min-width:0;box-sizing:border-box;border:1px solid var(--plotline-line);border-radius:8px;padding:12px;background:#fff;color:var(--plotline-ink);text-decoration:none;box-shadow:0 8px 18px rgba(30,37,43,.05)}.timeline-scene-card:hover{border-color:var(--plotline-accent);color:var(--plotline-ink)}.timeline-placeholder-scene,.timeline-placeholder-cell,.metric-point-placeholder{cursor:default;opacity:.72}.timeline-placeholder-scene{align-items:center;justify-content:center;border-style:dashed;color:var(--plotline-muted);background:rgba(255,255,255,.38);font-size:.86rem;font-weight:800;text-align:center}.timeline-placeholder-cell{border-style:dashed;background:repeating-linear-gradient(-45deg,rgba(216,221,216,.18) 0,rgba(216,221,216,.18) 7px,rgba(255,255,255,.18) 7px,rgba(255,255,255,.18) 14px)}.metric-point-placeholder::before{height:4px;background:rgba(102,113,123,.2);box-shadow:none}.timeline-scene-card.selected{border-color:var(--plotline-accent-dark);box-shadow:0 0 0 3px rgba(47,111,99,.16),0 10px 22px rgba(30,37,43,.08)}.scene-badge-row,.purpose-chip-row{display:flex;flex-wrap:wrap;gap:5px;align-items:center}.warning-placeholder{display:inline-flex;width:fit-content;border:1px dashed #d6b25e;border-radius:999px;padding:2px 8px;color:#755715;background:#fff8e8;font-size:.74rem;font-weight:700}.warning-placeholder.active{border-color:rgba(159,69,69,.36);color:#8a3434;background:rgba(255,232,232,.9);gap:5px;font-weight:800}.dependency-placeholder{display:inline-flex;width:fit-content;border:1px solid rgba(47,111,99,.2);border-radius:999px;padding:2px 8px;color:var(--plotline-accent-dark);background:rgba(47,111,99,.08);font-size:.74rem;font-weight:700}.purpose-chip{display:inline-flex;width:fit-content;border-radius:999px;padding:2px 7px;color:#38453e;background:#edf0eb;font-size:.72rem;font-weight:700}.future-lane-placeholder{border-top:1px dashed #cbd8d2;padding:8px 12px;color:var(--plotline-muted);font-size:.78rem;background:rgba(255,255,255,.45)}.metric-timeline-board{display:grid;gap:8px;width:max-content;min-width:100%;margin-top:14px;border-top:1px solid var(--plotline-line);padding-top:14px}.metric-shape-controls{position:sticky;left:0;z-index:6;display:grid;gap:8px;width:calc(var(--timeline-label-width) + (var(--scene-count)*var(--timeline-scene-width)) + (var(--scene-count)*var(--timeline-grid-gap)));min-width:100%;border-radius:8px;padding:10px;background:rgba(255,255,255,.88)}.metric-timeline-row{display:grid;grid-template-columns:var(--timeline-label-width) calc((var(--scene-count)*var(--timeline-scene-width)) + ((var(--scene-count) - 1)*var(--timeline-grid-gap)));gap:var(--timeline-grid-gap);align-items:stretch}.metric-lane-label{position:sticky;left:0;z-index:12;display:grid;align-content:start;gap:4px;min-height:320px;border:1px solid rgba(47,111,99,.18);border-radius:8px;padding:10px;color:var(--plotline-accent-dark);background:#fff;box-shadow:0 6px 14px rgba(30,37,43,.04)}.metric-lane-label span{color:var(--plotline-muted);font-size:.78rem;font-weight:600}.colour-swatch{display:inline-block;width:18px;height:18px;border:1px solid rgba(30,37,43,.18);border-radius:999px;vertical-align:middle}.plot-lane-board{position:relative;display:grid;gap:8px;width:max-content;min-width:100%;margin-top:14px;border-top:1px solid var(--plotline-line);padding-top:14px}.plot-lane-svg-overlay{position:absolute;inset:0 auto auto 0;z-index:4;pointer-events:none;overflow:visible}.plot-lane-svg-health-overlay{z-index:8}.plot-line-svg-path{fill:none;stroke-width:3.5;stroke-linecap:round;opacity:.72}.plot-line-svg-segment-dormant{stroke-dasharray:9 8;opacity:.48}.plot-line-svg-connector{fill:none;stroke-width:3;stroke-linecap:round;opacity:.58}.plot-line-svg-path.plotline-state-resolved,.plot-line-svg-path.plotline-state-questionable{stroke:#8c9491;opacity:.42}.plot-line-svg-path.plotline-state-abandoned{stroke:#9b2f36;opacity:.5}.plot-event-svg-node.plotline-state-resolved,.plot-event-svg-node.plotline-state-questionable{opacity:.88}.plot-event-svg-node.plotline-state-abandoned{opacity:.9}.plot-event-svg-node.plotline-state-abandoned line{stroke:#fff}.plotline-health-marker path,.plotline-health-marker circle{fill:#f4c430;stroke:#8a6712;stroke-width:1.5}.plotline-health-marker{pointer-events:visiblePainted}.plotline-health-marker line,.plotline-health-marker text{stroke:#5e4710;fill:#5e4710;stroke-width:1.6;stroke-linecap:round}.plotline-health-marker text{font-size:11px;font-weight:800;stroke-width:0;pointer-events:none}.plotline-health-count{fill:#fff;stroke:#8a6712;stroke-width:2;paint-order:stroke}.plotline-health-marker-dangling path,.plotline-health-marker-dangling circle{fill:#f8df8f}.plotline-health-marker-abandoned path,.plotline-health-marker-abandoned circle{fill:#d85c63;stroke:#8b1e2d}.plotline-health-marker-abandoned line{stroke:#fff}.plot-event-svg-node circle,.plot-event-svg-node ellipse,.plot-event-svg-node path{stroke:#fff;stroke-width:2}.plot-event-svg-node line,.plot-event-svg-node path[fill="none"]{stroke:#8b1e2d;stroke-width:3.4;stroke-linecap:round;stroke-linejoin:round}.plot-event-svg-node-reveal ellipse{stroke-width:2.4}.plot-event-svg-label{font-size:9.5px;font-weight:900;font-family:system-ui,-apple-system,"Segoe UI",sans-serif;paint-order:stroke;stroke:rgba(30,37,43,.22);stroke-width:.8px;pointer-events:none}.plot-event-svg-node-resolve path[fill="none"]{stroke:#fff}.lane-board-heading,.metric-lane-board-heading,.plot-lane-board-heading{position:sticky;left:0;z-index:6;display:flex;align-items:center;justify-content:space-between;gap:14px;width:calc(var(--timeline-label-width) + (var(--scene-count)*var(--timeline-scene-width)) + (var(--scene-count)*var(--timeline-grid-gap)));min-width:100%;margin-bottom:2px;border-radius:8px;padding:8px 10px;color:var(--plotline-accent-dark);background:rgba(255,255,255,.92);font-weight:700;box-shadow:0 8px 16px rgba(30,37,43,.05)}.lane-board-heading small,.metric-lane-board-heading small,.plot-lane-board-heading small{color:var(--plotline-muted);font-weight:500;white-space:nowrap}.timeline-heading-with-help{display:inline-flex;align-items:center;gap:6px;min-width:0}.plot-lane-row{display:grid;grid-template-columns:var(--timeline-label-width) repeat(var(--scene-count),var(--timeline-scene-width));gap:var(--timeline-grid-gap);align-items:stretch}.plot-lane-label{position:sticky;left:0;z-index:12;display:flex;align-items:center;gap:8px;min-height:46px;border:1px solid color-mix(in srgb,var(--plot-colour),#fff 55%);border-left:5px solid var(--plot-colour);border-radius:8px;padding:8px 10px;background:#fff;color:var(--plotline-ink);text-decoration:none;box-shadow:0 6px 14px rgba(30,37,43,.04)}.plot-lane-label:hover{color:var(--plotline-ink);border-color:var(--plot-colour)}.plot-lane-slots{display:contents}.plot-lane-slot{display:flex;flex-wrap:wrap;align-content:center;align-items:center;justify-content:center;gap:5px;min-height:46px;border:1px dashed #d8ddd8;border-radius:8px;padding:7px;background:rgba(255,255,255,.62)}.thread-marker{position:relative;z-index:5;display:inline-flex;align-items:center;justify-content:center;gap:4px;min-width:34px;height:30px;border:2px solid color-mix(in srgb,var(--plot-colour),#000 20%);border-radius:999px;padding:0 8px;color:var(--plotline-ink);background:color-mix(in srgb,var(--plot-colour),#fff 66%);font-size:.74rem;font-weight:900;text-decoration:none;box-shadow:0 3px 8px rgba(30,37,43,.14)}.plot-lane-board [data-plot-event-node]{opacity:1}.thread-marker:hover,.thread-marker:focus-visible{color:var(--plotline-ink);background:color-mix(in srgb,var(--plot-colour),#fff 48%);outline:3px solid rgba(47,111,99,.22);outline-offset:2px}.thread-marker.resolved{border-color:#5a8c60;background:#e6f4e7;color:#24512b}.thread-marker.contradicted{border-color:#b45c5c;background:#fff0f0;color:#7a2222}.thread-events-section{margin-top:16px}.thread-event-list{display:grid;gap:8px;margin-bottom:12px}.thread-event-item{display:flex;align-items:flex-start;justify-content:space-between;gap:10px;border:1px solid color-mix(in srgb,var(--plot-colour),#fff 55%);border-left:4px solid var(--plot-colour);border-radius:8px;padding:8px;background:#fff}.thread-event-item>div{display:grid;gap:3px}.thread-event-marker{display:inline-flex;align-items:center;justify-content:center;width:fit-content;min-width:24px;height:22px;border-radius:999px;padding:0 7px;background:color-mix(in srgb,var(--plot-colour),#fff 72%);font-size:.72rem;font-weight:800}.thread-event-create{border-top:1px solid var(--plotline-line);padding-top:12px}.asset-lane-board{display:grid;gap:8px;width:max-content;min-width:100%;margin-top:14px;border-top:1px solid var(--plotline-line);padding-top:14px}.asset-lane-row{display:grid;grid-template-columns:var(--timeline-label-width) repeat(var(--scene-count),var(--timeline-scene-width));gap:var(--timeline-grid-gap);align-items:stretch}.asset-lane-label{position:sticky;left:0;z-index:12;display:grid;gap:2px;min-height:46px;border:1px solid #d4d7df;border-left:5px solid #6b5b95;border-radius:8px;padding:8px 10px;background:#fff;color:var(--plotline-ink);text-decoration:none;box-shadow:0 6px 14px rgba(30,37,43,.04)}.asset-lane-label span{color:var(--plotline-muted);font-size:.75rem}.asset-lane-slots{display:contents}.asset-lane-slot{display:flex;flex-wrap:wrap;align-content:flex-start;gap:5px;min-height:46px;border:1px dashed #d8ddd8;border-radius:8px;padding:7px;background:rgba(250,249,255,.72)}.asset-marker,.asset-event-marker{display:inline-flex;align-items:center;justify-content:center;min-width:26px;height:24px;border:1px solid #7f70aa;border-radius:7px;padding:0 7px;color:#33284e;background:#eee9fb;font-size:.72rem;font-weight:800;text-decoration:none}.asset-marker:hover{color:#33284e;background:#dfd6f7}.asset-marker.timeline-marker-story-turn,.character-marker.timeline-marker-story-turn{border-width:2px}.asset-marker.timeline-marker-important,.character-marker.timeline-marker-important{box-shadow:inset 0 -3px 0 rgba(197,139,43,.36)}.asset-marker.timeline-marker-state-change,.character-marker.timeline-marker-state-change{border-style:double}.asset-marker.timeline-marker-transfer{box-shadow:inset 3px 0 0 rgba(47,111,99,.32)}.character-marker.timeline-marker-exit{opacity:.86;border-style:dashed}.asset-marker.timeline-marker-has-warning,.character-marker.timeline-marker-has-warning{box-shadow:0 0 0 2px rgba(179,95,59,.22)}.asset-events-section{margin-top:16px}.asset-event-list,.asset-mini-list{display:grid;gap:8px;margin-bottom:12px}.asset-event-item,.asset-mini-item{display:flex;align-items:flex-start;justify-content:space-between;gap:10px;border:1px solid #ded9ea;border-left:4px solid #6b5b95;border-radius:8px;padding:8px;background:#fff}.asset-event-item>div,.asset-mini-item>div{display:grid;gap:3px}.asset-create-form{border-top:1px solid var(--plotline-line);padding-top:12px}.asset-card-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:12px}.asset-card{display:grid;gap:12px;border:1px solid var(--plotline-line);border-radius:8px;padding:14px;background:#fff;box-shadow:0 8px 18px rgba(30,37,43,.04)}.asset-card h2{margin:0;font-size:1.1rem}.asset-card-footer{display:flex;flex-wrap:wrap;align-items:center;gap:6px}.asset-detail-grid{display:grid;grid-template-columns:minmax(260px,.8fr) minmax(320px,1.2fr);gap:14px}.character-lane-board{display:grid;gap:8px;width:max-content;min-width:100%;margin-top:14px;border-top:1px solid var(--plotline-line);padding-top:14px}.character-lane-row{display:grid;grid-template-columns:var(--timeline-label-width) repeat(var(--scene-count),var(--timeline-scene-width));gap:var(--timeline-grid-gap);align-items:stretch}.character-lane-label{position:sticky;left:0;z-index:12;display:grid;gap:2px;min-height:46px;border:1px solid #d7d4ce;border-left:5px solid #8a6f3d;border-radius:8px;padding:8px 10px;background:#fff;color:var(--plotline-ink);text-decoration:none;box-shadow:0 6px 14px rgba(30,37,43,.04)}.character-lane-label span{color:var(--plotline-muted);font-size:.75rem}.character-lane-slots{display:contents}.character-lane-slot{display:flex;flex-wrap:wrap;align-content:flex-start;gap:5px;min-height:46px;border:1px dashed #d8ddd8;border-radius:8px;padding:7px;background:rgba(255,252,246,.72)}.character-marker{display:inline-flex;align-items:center;justify-content:center;min-width:26px;height:24px;border:1px solid #9a7a3f;border-radius:999px;padding:0 7px;color:#4f3810;background:#fff2d7;font-size:.72rem;font-weight:800;text-decoration:none}.character-card{border-left:4px solid #8a6f3d}.character-section{margin-top:16px}.character-item{border-left-color:#8a6f3d}.character-appearance-card{display:grid;gap:8px;border:1px solid #d7d4ce;border-left:4px solid #8a6f3d;border-radius:8px;padding:10px;background:#fff}.character-appearance-summary{display:flex;align-items:flex-start;justify-content:space-between;gap:12px}.character-appearance-summary>div:first-child{display:grid;gap:3px}.character-appearance-actions{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:6px}.character-appearance-edit .asset-create-form{margin-top:8px;border-top:1px solid var(--plotline-line)}.word-companion-suggestion-panel{display:grid;gap:8px;margin-bottom:12px;border:1px solid rgba(138,111,61,.24);border-radius:8px;padding:10px;background:rgba(255,248,232,.72)}.word-companion-suggestion-list{display:grid;gap:8px}.word-companion-suggestion-item{display:flex;align-items:flex-start;justify-content:space-between;gap:10px;border:1px solid #ded9ea;border-left:4px solid #8a6f3d;border-radius:8px;padding:8px;background:#fff}.word-companion-suggestion-item>div:first-child{display:grid;gap:3px}.word-companion-suggestion-pill{margin-left:6px}.form-helper-message{margin:0 0 8px;font-size:.86rem;font-weight:700}.scene-number,.time-label{color:var(--plotline-muted);font-size:.82rem}.location-pill,.location-badge{display:inline-flex;align-items:center;width:fit-content;border:1px solid rgba(47,111,99,.18);border-radius:999px;padding:2px 7px;color:var(--plotline-accent-dark);background:rgba(47,111,99,.08);font-size:.74rem;font-weight:700}.scene-summary{display:-webkit-box;overflow:hidden;color:var(--plotline-muted);font-size:.88rem;-webkit-box-orient:vertical;-webkit-line-clamp:4}.timeline-empty-scene{justify-content:center;color:var(--plotline-muted);background:rgba(255,255,255,.58)}.form-control:focus,.form-select:focus,.form-check-input:focus{border-color:var(--plotline-accent);box-shadow:0 0 0 .2rem rgba(47,111,99,.16)}.scene-inspector-panel{position:sticky;top:76px;display:flex;flex-direction:column;max-height:calc(100vh - 96px);min-width:0;overflow:hidden;border:1px solid var(--plotline-line);border-radius:8px;background:#fff;box-shadow:0 14px 32px rgba(30,37,43,.08)}.inspector-header{position:sticky;top:0;z-index:5;display:flex;align-items:flex-start;justify-content:space-between;gap:12px;border-bottom:1px solid var(--plotline-line);padding:16px;background:#fff}.scene-inspector-body{flex:1 1 auto;min-height:0;overflow:auto;padding:16px}.inspector-header h2{margin:0;font-size:1.25rem}.scene-inspector-form{display:grid;gap:14px}.inspector-section{border-top:1px solid var(--plotline-line);padding-top:12px}.inspector-section:first-of-type{border-top:0;padding-top:0}.inspector-section h3{margin:0 0 10px;font-size:.95rem;color:var(--plotline-accent-dark)}.location-helper{border:1px solid rgba(138,111,61,.22);border-radius:8px;padding:10px;background:rgba(255,248,232,.74)}.location-warning-list{margin:0;padding-left:18px;color:#6f5526;font-size:.86rem}.location-tree{display:grid;gap:8px}.location-tree-row{display:flex;align-items:center;justify-content:space-between;gap:12px;border-bottom:1px solid var(--plotline-line);padding:10px 0 10px calc(var(--location-depth,0)*22px)}.location-tree-row:last-child{border-bottom:0}.location-tree-row>div:first-child{display:grid;gap:3px}.compact-buttons{flex-wrap:nowrap}.location-chip-list{display:flex;flex-wrap:wrap;gap:8px}.location-chip{border:1px solid var(--plotline-line);border-radius:8px;padding:7px 10px;background:#fff;text-decoration:none}.location-relationship-list{display:grid;gap:8px}.location-relationship-card{display:flex;justify-content:space-between;gap:12px;border:1px solid var(--plotline-line);border-radius:8px;padding:10px;background:#fff}.location-flags{display:flex;flex-wrap:wrap;gap:10px 16px;color:var(--plotline-muted);font-size:.86rem}.validation-summary,.warning-filter-panel{border:1px solid var(--plotline-line);border-radius:8px;margin-bottom:16px;padding:12px;background:#fff}.validation-summary{display:flex;flex-wrap:wrap;gap:12px;color:var(--plotline-muted)}.warning-dashboard-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px;margin-bottom:18px}.warning-count-row,.warning-card-title,.inspector-section-heading{display:flex;align-items:center;justify-content:space-between;gap:10px}.warning-list,.warning-mini-list{display:grid;gap:10px}.warning-card,.warning-mini-card{border:1px solid var(--plotline-line);border-radius:8px;padding:12px;background:#fff}.warning-card{display:grid;grid-template-columns:1fr auto;gap:12px}.warning-card p,.warning-mini-card p{margin:6px 0}.warning-actions{display:flex;align-items:flex-start;flex-wrap:wrap;gap:6px}.severity-pill{display:inline-flex;align-items:center;border-radius:999px;padding:2px 8px;font-size:.74rem;font-weight:800}.severity-pill.info{color:#365f7c;background:rgba(107,153,184,.14)}.severity-pill.warning{color:#7a5527;background:rgba(205,154,72,.17)}.severity-pill.error{color:#8a3434;background:rgba(190,83,83,.15)}.warning-mini-card{background:rgba(255,255,255,.76)}.dependency-columns{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}.dependency-card{display:grid;gap:3px;border:1px solid var(--plotline-line);border-radius:8px;margin-bottom:8px;padding:9px;background:rgba(255,255,255,.78)}.move-preview-panel{max-width:900px}.focused-validation-summary{display:flex;flex-wrap:wrap;gap:10px;border:1px solid rgba(47,111,99,.16);border-radius:8px;margin-top:12px;padding:10px;color:var(--plotline-muted);background:rgba(47,111,99,.05)}.inspector-purpose-list{grid-template-columns:1fr;max-height:210px}.metric-slider-stack{display:grid;gap:12px}.metric-slider{display:grid;gap:4px}.metric-slider-label{display:flex;justify-content:space-between;gap:10px;color:var(--plotline-muted);font-size:.86rem;font-weight:700}.metric-slider-label output{color:var(--plotline-accent-dark)}.metric-slider .form-range{accent-color:var(--plotline-accent)}.asset-importance-slider{border:1px solid var(--plotline-line);border-radius:8px;padding:10px 12px;background:rgba(47,111,99,.05)}.story-asset-checkbox-field{margin-top:1.95rem}.story-asset-event-item{justify-content:flex-start;gap:8px}.story-asset-event-item .asset-event-marker{flex:0 0 auto;min-width:1.55rem;width:auto}.story-asset-event-details{min-width:0}.scene-inspector-root{display:grid;gap:12px}.scene-overview-card{display:grid;gap:10px;border:1px solid rgba(47,111,99,.18);border-radius:10px;padding:12px;background:linear-gradient(180deg,rgba(47,111,99,.08),rgba(255,255,255,.88))}.scene-overview-card h3{margin:0;font-size:1.05rem}.scene-overview-card .muted{display:flex;flex-wrap:wrap;gap:7px;margin:0}.overview-chip-grid,.context-nav,.breadcrumb-trail,.inspector-nav-links{display:flex;flex-wrap:wrap;gap:7px}.overview-chip,.context-nav a,.breadcrumb-trail a,.breadcrumb-trail span{display:inline-flex;align-items:center;border:1px solid var(--plotline-line);border-radius:999px;padding:4px 9px;color:var(--plotline-muted);font-size:.78rem;font-weight:800;text-decoration:none;background:rgba(255,255,255,.72)}.overview-chip.attention{color:#7a5527;border-color:rgba(205,154,72,.35);background:rgba(205,154,72,.14)}.overview-outcome{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;margin:0;color:var(--plotline-muted)}.inspector-quick-nav{position:sticky;top:0;z-index:5;display:grid;gap:8px;border:1px solid var(--plotline-line);border-radius:10px;padding:10px;background:rgba(255,255,255,.94);box-shadow:0 10px 24px rgba(55,48,39,.08);backdrop-filter:blur(8px)}.inspector-nav-links a{border:1px solid var(--plotline-line);border-radius:999px;padding:4px 8px;color:var(--plotline-muted);font-size:.76rem;font-weight:800;text-decoration:none}.inspector-nav-links a:hover,.inspector-nav-links a.active{color:var(--plotline-accent-dark);border-color:rgba(47,111,99,.35);background:rgba(47,111,99,.08)}.inspector-accordion-toggle{display:flex;align-items:center;justify-content:space-between;width:100%;border:0;padding:0;color:var(--plotline-ink);font-size:.95rem;font-weight:900;text-align:left;background:transparent}.inspector-accordion-toggle::before{content:"+";display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;border-radius:999px;margin-right:7px;color:var(--plotline-accent-dark);background:rgba(47,111,99,.09)}.inspector-section.is-open>.inspector-accordion-toggle::before{content:"-"}.inspector-accordion-toggle span:first-child{margin-right:auto}.accordion-count{color:var(--plotline-muted);font-size:.75rem}.inspector-subheading{margin:14px 0 8px;color:var(--plotline-muted);font-size:.88rem;font-weight:900}.inspector-accordion-body{display:none;margin-top:12px}.inspector-section.is-open>.inspector-accordion-body{display:block}.inspector-section.is-filtered-out{display:none}.breadcrumb-trail{margin-bottom:12px}.breadcrumb-trail a:hover,.context-nav a:hover{color:var(--plotline-accent-dark);border-color:rgba(47,111,99,.35);background:rgba(47,111,99,.08)}.context-header,.working-context-banner{display:flex;align-items:center;justify-content:space-between;gap:14px;border:1px solid var(--plotline-line);border-radius:10px;margin-bottom:16px;padding:10px 12px;background:rgba(255,255,255,.84);box-shadow:0 10px 24px rgba(55,48,39,.05)}.context-title{display:grid;gap:2px}.context-title strong{color:var(--plotline-ink)}.health-kpi-grid,.analytics-grid-two,.analytics-grid-three{display:grid;gap:14px;margin:18px 0}.health-kpi-grid{grid-template-columns:repeat(4,minmax(0,1fr))}.health-kpi-grid .plain-card{display:grid;gap:4px}.health-kpi-grid strong{color:var(--plotline-ink);font-size:2rem;line-height:1}.analytics-grid-two{grid-template-columns:repeat(2,minmax(0,1fr))}.analytics-grid-three{grid-template-columns:repeat(3,minmax(0,1fr))}.analytics-section{border:1px solid var(--plotline-line);border-radius:10px;margin:18px 0;padding:16px;background:rgba(255,255,255,.84);box-shadow:0 14px 34px rgba(55,48,39,.07)}.analytics-section-heading{display:flex;align-items:baseline;justify-content:space-between;gap:12px;margin-bottom:14px}.analytics-section-heading h2,.plain-card h3{margin:0}.analytics-metric-stack{display:grid;gap:12px;overflow-x:auto;padding-bottom:4px}.metric-shape-chart{display:grid;gap:12px}.metric-shape-intro{max-width:760px;margin:0;color:var(--plotline-muted)}.metric-toggle-row{display:flex;flex-wrap:wrap;gap:8px}.metric-toggle-pill{display:inline-flex;align-items:center;gap:6px;border:1px solid rgba(82,75,65,.16);border-radius:999px;padding:5px 9px;color:var(--plotline-muted);font-size:.78rem;font-weight:800;background:rgba(255,255,255,.78);cursor:pointer}.metric-toggle-pill::before{content:"";width:10px;height:10px;border-radius:999px;background:var(--metric-colour)}.metric-toggle-pill input{margin:0;accent-color:var(--metric-colour)}.timeline-metric-edit-toolbar{display:flex;flex-wrap:wrap;gap:8px;align-items:end}.timeline-metric-edit-select{display:grid;gap:3px;min-width:180px;color:var(--plotline-muted);font-size:.78rem;font-weight:800}.timeline-metric-edit-status{align-self:center;border:1px solid rgba(47,111,99,.18);border-radius:999px;padding:5px 9px;color:var(--plotline-muted);font-size:.78rem;font-weight:800;background:rgba(255,255,255,.72)}.timeline-metric-edit-hint{font-size:.82rem}.metric-chart-frame canvas.metric-curve-editing{cursor:ns-resize}.metric-chart-frame{position:relative;min-height:320px;border:1px solid var(--plotline-line);border-radius:10px;padding:14px 12px 32px;background:linear-gradient(180deg,rgba(255,255,255,.92),rgba(247,245,240,.76))}.metric-timeline-frame{width:calc((var(--scene-count)*var(--timeline-scene-width)) + ((var(--scene-count) - 1)*var(--timeline-grid-gap)))}.metric-chart-frame canvas{width:100%;height:300px}.metric-timeline-board .metric-graph-stack{width:max-content;min-width:100%}.metric-timeline-board .metric-graph-row{grid-template-columns:var(--timeline-label-width) repeat(var(--scene-count),var(--timeline-scene-width));gap:var(--timeline-grid-gap);min-width:100%}.metric-timeline-board .metric-graph-points{display:contents}.metric-timeline-board .metric-point{border:1px solid rgba(47,111,99,.12);border-radius:8px;background:rgba(255,255,255,.62)}.metric-raw-details{border-top:1px solid var(--plotline-line);padding-top:8px}.metric-raw-details summary{color:var(--plotline-muted);font-size:.82rem;font-weight:800;cursor:pointer}.timeline-control-panel{display:grid;gap:12px;border:1px solid var(--plotline-line);border-radius:10px;margin-bottom:16px;padding:12px;background:rgba(255,255,255,.84);box-shadow:0 10px 24px rgba(55,48,39,.05)}.timeline-filter-drawer summary{color:var(--plotline-ink);font-weight:900;cursor:pointer}.timeline-filter-grid{display:grid;grid-template-columns:repeat(6,minmax(130px,1fr));gap:10px;margin-top:12px}.timeline-filter-checks,.timeline-filter-actions,.timeline-visibility-panel,.timeline-preset-panel,.preset-chip-row{display:flex;flex-wrap:wrap;align-items:center;gap:8px}.timeline-filter-checks{grid-column:span 3;color:var(--plotline-muted);font-size:.82rem;font-weight:700}.timeline-filter-actions{grid-column:span 3;justify-content:flex-end}.timeline-visibility-panel label,.preset-chip{display:inline-flex;align-items:center;gap:6px;border:1px solid var(--plotline-line);border-radius:999px;padding:4px 8px;color:var(--plotline-muted);font-size:.78rem;font-weight:800;background:rgba(255,255,255,.76)}.timeline-preset-panel form{display:inline-flex;align-items:center;gap:6px}.preset-chip a{color:var(--plotline-accent-dark);text-decoration:none}.preset-chip button{border:0;color:var(--plotline-muted);background:transparent;font-weight:900}.timeline-focus-banner{display:flex;align-items:center;justify-content:space-between;gap:12px;border:1px solid rgba(47,111,99,.22);border-radius:10px;margin-bottom:16px;padding:10px 12px;background:rgba(47,111,99,.08)}.thread-marker-icon{display:inline-flex;align-items:center;justify-content:center;min-width:16px;font-size:.78rem;font-weight:900}.thread-marker-type-start .thread-marker-icon,.thread-marker-type-resolve .thread-marker-icon,.thread-marker-type-abandon .thread-marker-icon,.thread-marker-type-twist .thread-marker-icon{font-size:.9rem}.thread-marker-type-start{border-radius:8px 999px 999px 8px}.thread-marker-type-twist{border-color:#b8762b;background:#fff4dc}.thread-marker-type-branch,.thread-marker-type-split,.thread-marker-type-merge{border-color:#6750a4;background:#f0ebff}.thread-marker-type-reveal .thread-marker-icon{border:1px solid currentColor;border-radius:999px;font-size:0}.thread-marker-type-reveal .thread-marker-icon::after{content:"";width:4px;height:4px;border-radius:999px;background:currentColor}.timeline-navigation-card{display:grid;grid-template-areas:"icon copy" "icon actions";grid-template-columns:auto minmax(0,620px);gap:8px 14px;align-items:center;justify-content:center;border:1px solid rgba(47,111,99,.42);border-left:5px solid var(--plotline-accent);border-radius:8px;margin:0 0 12px;padding:14px 16px;max-height:280px;overflow:hidden;color:var(--plotline-ink);background:linear-gradient(135deg,rgba(238,245,242,.98),rgba(255,255,255,.94));box-shadow:0 10px 26px rgba(30,37,43,.08);opacity:1;transform:translateY(0);transition:opacity 1.15s ease,max-height 1.2s ease,margin 1.2s ease,padding 1.2s ease,transform 1.15s ease}.timeline-navigation-card[hidden]{display:none}.timeline-navigation-card.is-dismissing{margin-bottom:0;padding-top:0;padding-bottom:0;max-height:0;opacity:0;transform:translateY(-6px)}.timeline-navigation-card-icon{grid-area:icon;display:grid;place-items:center;width:42px;height:42px;border-radius:50%;color:#fff;background:var(--plotline-accent);font-size:1.25rem;font-weight:900}.timeline-navigation-card-copy{grid-area:copy;text-align:center}.timeline-navigation-card-copy h2{margin:0 0 6px;color:var(--plotline-accent-dark);font-size:1rem;font-weight:900}.timeline-navigation-card-copy p{margin:2px 0;color:var(--plotline-ink);font-size:.9rem}.timeline-navigation-card-actions{grid-area:actions;display:flex;flex-wrap:wrap;gap:8px;justify-content:center}.timeline-horizontal-overflow{transition:box-shadow .18s ease}.timeline-horizontal-overflow.has-scroll-left{box-shadow:inset 18px 0 18px -20px rgba(30,37,43,.55)}.timeline-horizontal-overflow.has-scroll-right{box-shadow:inset -18px 0 18px -20px rgba(30,37,43,.55)}.timeline-horizontal-overflow.has-scroll-left.has-scroll-right{box-shadow:inset 18px 0 18px -20px rgba(30,37,43,.55),inset -18px 0 18px -20px rgba(30,37,43,.55)}[data-theme="dark"] .timeline-navigation-card{border-color:rgba(111,169,155,.52);border-left-color:#6fa99b;color:#f4eadc;background:linear-gradient(135deg,rgba(34,83,74,.72),rgba(32,31,34,.96));box-shadow:0 12px 28px rgba(0,0,0,.28)}[data-theme="dark"] .timeline-navigation-card-copy h2,[data-theme="dark"] .timeline-navigation-card-copy p{color:#f4eadc}[data-theme="dark"] .timeline-horizontal-overflow.has-scroll-left{box-shadow:inset 18px 0 18px -20px rgba(244,234,220,.55)}[data-theme="dark"] .timeline-horizontal-overflow.has-scroll-right{box-shadow:inset -18px 0 18px -20px rgba(244,234,220,.55)}[data-theme="dark"] .timeline-horizontal-overflow.has-scroll-left.has-scroll-right{box-shadow:inset 18px 0 18px -20px rgba(244,234,220,.55),inset -18px 0 18px -20px rgba(244,234,220,.55)}@media(prefers-reduced-motion:reduce){.timeline-navigation-card{transition:opacity .12s ease}}.timeline-scene-card.filter-dim,.timeline-scene-card.focus-dim,.lane-dim{opacity:.35}.timeline-scene-card.focus-match,.timeline-scene-card.filter-match.focus-match{outline:3px solid rgba(47,111,99,.32);box-shadow:0 12px 26px rgba(47,111,99,.16)}.timeline-section-hidden{display:none!important}.hide-scene-cards .timeline-scene-card{display:none}.timeline-control-panel{position:sticky;top:56px;z-index:18}.timeline-control-select{padding-right:6px}.timeline-control-select .form-select{width:auto;min-width:132px;border:0;padding-top:2px;padding-bottom:2px;background-color:transparent;color:var(--plotline-accent-dark);font-weight:800}.timeline-jump-panel{display:grid;grid-template-columns:auto minmax(180px,1.2fr) minmax(180px,1fr) minmax(170px,.9fr) minmax(180px,1fr) auto;gap:8px;align-items:center;width:100%}.timeline-shortcut-hint{color:var(--plotline-muted);font-size:.76rem;font-weight:700;white-space:nowrap}.timeline-minimap{display:flex;align-items:stretch;gap:4px;margin:0 0 12px;padding:8px;max-width:100%;min-width:0;overflow-x:auto;overflow-y:hidden;overscroll-behavior-x:contain;scrollbar-gutter:stable;border:1px solid rgba(47,111,99,.18);border-radius:8px;background:rgba(255,255,255,.72)}.timeline-minimap button{position:relative;flex:0 0 max(42px,calc(var(--chapter-scenes)*18px));min-width:42px;min-height:34px;border:1px solid rgba(47,111,99,.18);border-radius:7px;color:var(--plotline-accent-dark);background:linear-gradient(180deg,#f8fbf9 0%,#edf4f1 100%);font-size:.72rem;font-weight:800}.timeline-minimap button.is-active{border-color:var(--plotline-accent);color:#fff;background:linear-gradient(180deg,var(--plotline-accent) 0%,var(--plotline-accent-dark) 100%);box-shadow:0 0 0 2px rgba(47,111,99,.14)}.timeline-minimap button::after{content:"";position:absolute;right:5px;bottom:5px;width:calc(var(--chapter-warnings)*4px);max-width:28px;height:4px;border-radius:999px;background:#b45c5c;opacity:.75}.timeline-drag-palette,.drag-drop-panel{border:1px solid rgba(47,111,99,.18);border-radius:10px;margin-bottom:12px;padding:12px;background:rgba(255,255,255,.84);box-shadow:0 10px 24px rgba(55,48,39,.05)}.timeline-drag-palette{display:grid;grid-template-columns:minmax(220px,.35fr) minmax(0,1fr);gap:12px;align-items:center}.drag-chip-group{display:flex;flex-wrap:wrap;gap:6px;max-height:104px;overflow:auto;padding-right:4px}.drag-chip{display:inline-flex;align-items:center;border:1px solid var(--plotline-line);border-radius:999px;padding:4px 9px;background:#fff;color:var(--plotline-ink);font-size:.78rem;font-weight:800;cursor:grab}.drag-chip.character{border-color:#dacb9e;background:#fff8e8}.drag-chip.asset{border-color:#ded9ea;background:#f4f0ff}.drag-chip.location{border-color:rgba(47,111,99,.18);background:#eef8f4}.is-dragging{opacity:.55}.drop-target-active{outline:3px solid rgba(47,111,99,.28);outline-offset:2px}.timeline-chapter.chapter-drop-active,.timeline-scenes.drop-chapter-end{background:rgba(47,111,99,.06)}.timeline-scenes.drop-chapter-end::after{content:"Drop scene at end of chapter";display:flex;align-items:center;justify-content:center;min-width:var(--timeline-scene-width);min-height:74px;border:2px dashed rgba(197,139,43,.48);border-radius:12px;color:#7a5527;background:rgba(255,248,232,.82);font-size:.8rem;font-weight:900}.timeline-scene-card.drop-before{box-shadow:inset 5px 0 0 #c58b2b,0 12px 26px rgba(197,139,43,.16)}.timeline-scene-card.drop-after{box-shadow:inset -5px 0 0 #c58b2b,0 12px 26px rgba(197,139,43,.16)}.drag-drop-panel{position:sticky;top:132px;z-index:19}.drag-drop-panel-header{display:flex;align-items:flex-start;justify-content:space-between;gap:12px}.drag-drop-panel h2{margin:0;font-size:1.08rem}.drag-drop-form{border-top:1px solid var(--plotline-line);margin-top:10px;padding-top:10px}.scene-move-modal-content{border:1px solid rgba(47,111,99,.18);border-radius:14px;background:var(--plotline-surface);color:var(--plotline-ink);box-shadow:0 24px 70px rgba(55,48,39,.22)}.scene-move-modal-content .modal-header,.scene-move-modal-content .modal-footer{border-color:var(--plotline-line)}.scene-move-modal-content .modal-title{margin:0;color:var(--plotline-ink);font-size:1.2rem;font-weight:900}.scene-move-summary{margin:0 0 12px;color:var(--plotline-ink);font-size:1rem;font-weight:800}[data-theme="dark"] .scene-move-modal-content{background:#201f22;color:#f4eadc;border-color:rgba(244,234,220,.16);box-shadow:0 24px 70px rgba(0,0,0,.55)}[data-theme="dark"] .scene-move-modal-content .modal-title,[data-theme="dark"] .scene-move-summary{color:#f4eadc}[data-theme="dark"] .scene-move-modal-content .modal-header,[data-theme="dark"] .scene-move-modal-content .modal-footer{border-color:rgba(244,234,220,.14)}[data-theme="dark"] .scene-move-modal-content .btn-close{filter:invert(1) grayscale(100%)}.plain-preview{border:1px solid rgba(197,139,43,.28);border-radius:8px;margin:10px 0 0;padding:8px 10px;color:#5e4518;background:#fff8e8;font-size:.86rem;font-weight:800}.drag-check-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px 10px;color:var(--plotline-muted);font-size:.82rem;font-weight:700}.timeline-section-header,.lane-board-heading,.pacing-heading{position:sticky;left:0;z-index:6}.timeline-section-header{display:flex;align-items:center;justify-content:space-between;gap:10px;width:calc(var(--timeline-label-width) + (var(--scene-count)*var(--timeline-scene-width)) + (var(--scene-count)*var(--timeline-grid-gap)));min-width:100%;margin-bottom:10px;border-radius:8px;padding:8px 10px;background:rgba(255,255,255,.92);box-shadow:0 8px 16px rgba(30,37,43,.05)}.timeline-section-header button,.lane-board-heading button,.plot-lane-board-heading button,.pacing-heading button,.lane-group-heading{border:0;padding:0;color:var(--plotline-accent-dark);background:transparent;font:inherit;font-weight:900;text-align:left}.timeline-section-header button::before,.lane-board-heading button::before,.plot-lane-board-heading button::before,.pacing-heading button::before,.lane-group-heading::before{content:"v";display:inline-block;margin-right:6px;color:var(--plotline-muted);font-size:.72rem}.timeline-section-header button.is-collapsed::before,.lane-board-heading button.is-collapsed::before,.plot-lane-board-heading button.is-collapsed::before,.pacing-heading button.is-collapsed::before,.lane-group-heading.is-collapsed::before{content:">"}.lane-group{display:grid;gap:7px}.character-lane-group-body{display:grid;gap:7px}.lane-group-heading{position:sticky;left:0;z-index:6;width:var(--timeline-label-width);border-top:1px solid rgba(47,111,99,.12);padding:7px 8px 2px;color:var(--plotline-muted);background:rgba(247,250,248,.96);font-size:.78rem;text-transform:uppercase}.timeline-section-collapsed{display:none!important}.timeline-chapter-title{position:sticky;top:0;z-index:5;background:rgba(238,245,242,.96);backdrop-filter:blur(6px)}.scene-pov-label,.metric-mini-summary{display:inline-flex;width:fit-content;border-radius:999px;padding:2px 7px;font-size:.72rem;font-weight:800}.scene-pov-label{color:#514018;background:#fff3d3}.metric-mini-summary{color:var(--plotline-accent-dark);background:rgba(47,111,99,.08)}.scene-overview-panel{display:none;gap:8px;margin-top:4px}.scene-overview-section{display:grid;gap:4px}.scene-overview-label{color:var(--plotline-muted);font-size:.68rem;font-weight:900;letter-spacing:.06em;text-transform:uppercase}.scene-overview-chip-row{display:flex;flex-wrap:wrap;gap:5px;min-width:0}.scene-overview-chip,.scene-overview-empty,.scene-overview-brief{display:inline-flex;width:fit-content;max-width:100%;border-radius:999px;padding:3px 8px;background:rgba(47,111,99,.08);color:var(--plotline-ink);font-size:.72rem;font-weight:750;line-height:1.25;overflow-wrap:anywhere}.scene-overview-chip.is-pov{border:1px solid rgba(197,139,43,.38);background:#fff3d3}.scene-overview-chip.is-important{border:1px solid rgba(103,80,164,.3);background:#f0edf8}.scene-overview-chip.is-more,.scene-overview-empty{color:var(--plotline-muted);background:rgba(102,113,123,.08)}.scene-overview-brief{display:block;width:auto;border-radius:8px;background:rgba(255,255,255,.62);color:var(--plotline-muted);font-weight:600}.timeline-scene-card.search-hit,.timeline-scene-card.keyboard-focus{outline:3px solid rgba(197,139,43,.34);box-shadow:0 12px 26px rgba(197,139,43,.16)}.timeline-scene-card.search-dim{opacity:.28}.thread-marker,.asset-marker,.character-marker{transition:transform .12s ease,box-shadow .12s ease}.thread-marker:hover,.asset-marker:hover,.character-marker:hover{transform:translateY(-1px);box-shadow:0 6px 12px rgba(30,37,43,.12)}.timeline-filtered-root.density-compact{--timeline-scene-width:170px;--timeline-grid-gap:6px}.timeline-filtered-root.density-expanded{--timeline-scene-width:280px;--timeline-grid-gap:14px}.timeline-filtered-root.density-compact .timeline-scene-card,.timeline-filtered-root.zoom-book .timeline-scene-card{gap:4px;padding:9px}.timeline-filtered-root.density-compact .scene-summary,.timeline-filtered-root.density-compact .purpose-chip-row,.timeline-filtered-root.density-compact .metric-mini-summary,.timeline-filtered-root.zoom-book .scene-summary,.timeline-filtered-root.zoom-book .purpose-chip-row,.timeline-filtered-root.zoom-book .metric-mini-summary,.timeline-filtered-root.zoom-book .location-pill,.timeline-filtered-root.zoom-book .scene-pov-label{display:none}.timeline-filtered-root.zoom-book{--timeline-scene-width:150px;--timeline-grid-gap:6px}.timeline-filtered-root.zoom-scene-detail{--timeline-scene-width:300px}.timeline-filtered-root.zoom-scene-detail .scene-summary{-webkit-line-clamp:7}.timeline-filtered-root.zoom-scene-overview{--timeline-scene-width:380px}.timeline-filtered-root.zoom-scene-overview .timeline-scenes{min-height:320px}.timeline-filtered-root.zoom-scene-overview .timeline-scene-card{gap:8px;padding:14px}.timeline-filtered-root.zoom-scene-overview .scene-summary{display:none}.timeline-filtered-root.zoom-scene-overview .scene-overview-panel{display:grid}.timeline-filtered-root.density-expanded .timeline-scenes{min-height:230px}.timeline-control-panel{position:relative;top:auto;z-index:4;display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin-bottom:10px;padding:8px;box-shadow:none}.timeline-filter-drawer,.timeline-control-group{border:1px solid var(--plotline-line);border-radius:999px;background:rgba(255,255,255,.82)}.timeline-filter-drawer[open],.timeline-control-group[open]{border-radius:10px;flex-basis:100%}.timeline-filter-drawer summary,.timeline-control-group summary{min-width:max-content;padding:5px 10px;color:var(--plotline-accent-dark);font-size:.82rem;font-weight:900;cursor:pointer;list-style:none}.timeline-filter-drawer summary::-webkit-details-marker,.timeline-control-group summary::-webkit-details-marker,.timeline-drag-palette summary::-webkit-details-marker{display:none}.timeline-filter-drawer summary::after,.timeline-control-group summary::after,.timeline-drag-palette summary::after{content:" v";color:var(--plotline-muted);font-size:.72rem}.timeline-filter-drawer[open] summary::after,.timeline-control-group[open] summary::after,.timeline-drag-palette[open] summary::after{content:" ^"}.timeline-filter-grid{grid-template-columns:repeat(auto-fit,minmax(145px,1fr));gap:8px;max-height:min(48vh,430px);overflow:auto;padding:0 10px 10px}.timeline-filter-grid .form-label{margin-bottom:2px;font-size:.72rem;font-weight:800}.timeline-filter-checks,.timeline-filter-actions{grid-column:1/-1}.timeline-visibility-panel,.timeline-jump-panel,.timeline-preset-panel{padding:0 10px 10px}.timeline-jump-panel{grid-template-columns:minmax(180px,1.5fr) repeat(3,minmax(150px,1fr))}.timeline-shortcut-hint{grid-column:1/-1}.timeline-preset-panel form{flex-wrap:nowrap}.timeline-preset-panel .form-control{width:150px}.timeline-preset-panel .btn,.timeline-filter-actions .btn{white-space:nowrap}.timeline-drag-palette{display:block;margin-bottom:8px;padding:7px 9px;box-shadow:none}.timeline-drag-palette summary{color:var(--plotline-accent-dark);font-size:.82rem;font-weight:900;cursor:pointer}.timeline-drag-palette .drag-chip-group{margin-top:8px}.drag-drop-panel{position:relative;top:auto;z-index:9;box-shadow:0 12px 28px rgba(30,37,43,.08)}.timeline-filtered-root,.timeline-filtered-root.density-compact,.timeline-filtered-root.zoom-book{--timeline-scene-width:220px;--timeline-grid-gap:10px}.timeline-filtered-root.density-expanded,.timeline-filtered-root.zoom-scene-detail{--timeline-scene-width:290px}.timeline-filtered-root.density-compact.zoom-book{--timeline-scene-width:200px}.timeline-chapter,.timeline-scene-card,.timeline-empty-scene{overflow-wrap:normal;word-break:normal}.timeline-scene-card strong,.timeline-chapter-title strong,.plot-lane-label strong,.asset-lane-label strong,.character-lane-label strong{min-width:0;white-space:normal;word-break:normal;overflow-wrap:break-word}.timeline-scene-card{cursor:grab}.timeline-scene-card:active,.drag-chip:active,[draggable="true"]:active{cursor:grabbing}body.drag-active .timeline-scene-card,body.dragging-asset [data-asset-drop-target],body.dragging-location [data-drag-type="location"]{transition:outline-color .12s ease,box-shadow .12s ease,opacity .12s ease}body.dragging-character .timeline-scene-card,body.dragging-asset .timeline-scene-card,body.dragging-scene .timeline-scene-card,body.dragging-scene .timeline-scenes[data-chapter-drop-target],body.dragging-asset [data-asset-drop-target],body.dragging-location [data-drag-type="location"]{outline:1px dashed rgba(47,111,99,.22);outline-offset:2px}.is-dragging{opacity:.42;transform:scale(.98)}.drop-target-active{outline:3px solid rgba(47,111,99,.42)!important;outline-offset:3px}.analytics-metric-row{display:grid;grid-template-columns:170px minmax(560px,1fr);gap:12px;align-items:stretch}.analytics-metric-label{display:flex;align-items:center;border-right:1px solid var(--plotline-line);color:var(--plotline-muted);font-weight:800}.analytics-sparkline{display:grid;grid-template-columns:repeat(var(--point-count),minmax(28px,1fr));align-items:end;gap:5px;min-height:88px;border-bottom:1px solid rgba(47,111,99,.25);padding-top:10px}.analytics-bar{position:relative;display:flex;align-items:end;justify-content:center;min-height:12px;height:max(12px,var(--bar-height));border-radius:6px 6px 2px 2px;color:var(--plotline-accent-dark);text-decoration:none;background:linear-gradient(180deg,rgba(47,111,99,.58),rgba(47,111,99,.18))}.analytics-bar:hover{background:linear-gradient(180deg,rgba(47,111,99,.82),rgba(47,111,99,.28))}.analytics-bar span{position:absolute;bottom:calc(100% + 3px);color:var(--plotline-muted);font-size:.68rem;font-weight:800}.analytics-list-item,.analytics-link-row,.analytics-count-row,.purpose-stat-row{border-top:1px solid var(--plotline-line);padding:9px 0}.analytics-list-item{display:grid;gap:3px}.analytics-list-item p{margin:0}.analytics-link-row,.analytics-count-row{display:flex;align-items:center;justify-content:space-between;gap:12px}.analytics-link-row{color:inherit;text-decoration:none}.analytics-link-row:hover{color:var(--plotline-accent-dark)}.analytics-link-row span,.analytics-link-row strong{min-width:0}.purpose-stat-row{display:grid;grid-template-columns:minmax(120px,1fr) minmax(90px,1.5fr) 42px;align-items:center;gap:10px}.purpose-stat-bar{overflow:hidden;height:8px;border-radius:999px;background:rgba(47,111,99,.08)}.purpose-stat-bar span{display:block;height:100%;border-radius:inherit;background:var(--plotline-accent)}.inspector-actions{position:sticky;bottom:-16px;display:flex;gap:8px;border-top:1px solid var(--plotline-line);margin:2px -16px -16px;padding:12px 16px;background:rgba(255,255,255,.95);backdrop-filter:blur(8px)}.story-bible-heading{align-items:end}.story-bible-search{display:flex;gap:8px;min-width:min(100%,420px)}.story-bible-search .form-control{min-width:0}.story-bible-nav{position:sticky;top:72px;z-index:4;display:flex;flex-wrap:wrap;gap:8px;margin:0 0 18px;padding:10px;border:1px solid var(--plotline-line);border-radius:12px;background:rgba(250,249,246,.92);backdrop-filter:blur(10px)}.story-bible-nav a,.story-bible-actions a{display:inline-flex;align-items:center;border-radius:999px;padding:6px 10px;background:rgba(47,111,99,.08);color:var(--plotline-ink);font-size:.86rem;font-weight:650;text-decoration:none}.story-bible-nav a:hover,.story-bible-actions a:hover{background:rgba(47,111,99,.16)}.story-bible-section{margin:0 0 28px}.story-bible-section-heading{display:flex;align-items:end;justify-content:space-between;gap:16px;margin-bottom:12px}.story-bible-section-heading h2{margin:0}.soft-count{color:var(--plotline-muted);font-size:.9rem;font-weight:650;white-space:nowrap}.story-bible-grid,.story-bible-search-results{display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:14px}.story-bible-grid-compact{grid-template-columns:repeat(auto-fit,minmax(260px,1fr))}.story-bible-card{border:1px solid var(--plotline-line);border-radius:14px;padding:14px;background:rgba(255,255,255,.86);box-shadow:0 14px 34px rgba(36,32,26,.06)}.story-bible-card h3{margin:0 0 8px;font-size:1.05rem}.story-bible-card h4{margin:14px 0 8px;font-size:.96rem}.story-bible-card p{color:var(--plotline-muted)}.story-bible-card-title{display:flex;align-items:start;justify-content:space-between;gap:10px}.story-bible-card-title span{border:1px solid var(--plotline-line);border-radius:999px;padding:3px 8px;background:rgba(250,249,246,.9);color:var(--plotline-muted);font-size:.78rem;font-weight:700;white-space:nowrap}.story-bible-meta{display:flex;flex-wrap:wrap;gap:6px;margin:10px 0}.story-bible-meta span{border-radius:999px;padding:4px 8px;background:rgba(36,32,26,.05);color:var(--plotline-muted);font-size:.78rem;font-weight:650}.story-bible-facts{display:grid;grid-template-columns:max-content minmax(0,1fr);gap:6px 10px;margin:12px 0}.story-bible-facts dt{color:var(--plotline-muted);font-size:.78rem;font-weight:800;text-transform:uppercase}.story-bible-facts dd{margin:0;min-width:0;overflow-wrap:anywhere}.story-bible-actions{display:flex;flex-wrap:wrap;gap:8px;margin-top:12px}.story-bible-link-list{display:grid;gap:8px;margin:0;padding:0;list-style:none}.story-bible-link-list li{display:grid;gap:2px;padding:8px 0;border-bottom:1px solid rgba(36,32,26,.08)}.story-bible-link-list li:last-child{border-bottom:0}.story-bible-link-list span{color:var(--plotline-muted);font-size:.88rem}.story-bible-timeline-summary{display:grid;gap:14px}.story-bible-wide-card{max-width:none}.story-bible-chapter-summary{border-top:1px solid var(--plotline-line);padding-top:8px}.story-bible-scene-summary{display:grid;grid-template-columns:minmax(220px,1.5fr) repeat(3,minmax(120px,.8fr));gap:8px;padding:9px 0;border-top:1px solid rgba(36,32,26,.08)}.story-bible-scene-summary p{grid-column:1/-1;margin:0}.story-bible-scene-summary span{color:var(--plotline-muted);font-size:.88rem}.attention-list{display:grid;gap:10px}.attention-list article{display:grid;grid-template-columns:max-content minmax(0,1fr) auto;align-items:center;gap:10px;border:1px solid var(--plotline-line);border-radius:12px;padding:10px 12px;background:rgba(255,255,255,.82)}.attention-list p{grid-column:2/-1;margin:0;color:var(--plotline-muted)}.writer-workspace-form,.writer-add-form,.writer-edit-form,.chapter-goal-form{display:grid;gap:10px}.writer-checkbox-grid{display:flex;flex-wrap:wrap;gap:8px 14px}.writer-checkbox-grid label{display:inline-flex;align-items:center;gap:6px;color:var(--plotline-muted);font-size:.86rem;font-weight:650}.writer-priority-control{display:grid;grid-template-columns:minmax(0,1fr) max-content;align-items:center;gap:12px}.writer-priority-control .form-range{min-width:0}.writer-note-list,.writer-queue-list{display:grid;gap:10px}.writer-mini-card{border:1px solid var(--plotline-line);border-radius:12px;padding:10px;background:rgba(255,255,255,.72)}.writer-mini-card summary{display:flex;align-items:center;gap:8px;cursor:pointer}.writer-mini-card summary strong{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.attachment-card-list{display:grid;gap:10px}.attachment-summary{align-items:center}.attachment-kind{border-radius:999px;padding:3px 8px;background:rgba(47,111,99,.1);color:var(--plotline-accent);font-size:.76rem;font-weight:800;text-transform:uppercase}.attachment-card-body{display:grid;gap:6px;margin-top:10px}.attachment-card-body p{margin:0}.attachment-add-card{margin-top:10px}.writer-checklist{display:grid;gap:6px}.writer-checklist-row,.writer-add-inline{display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:8px}.writer-remove-inline{display:flex;justify-content:end;margin:-2px 0 4px}.writer-dashboard-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px;margin-bottom:26px}.writer-dashboard-panel{border:1px solid var(--plotline-line);border-radius:14px;padding:14px;background:rgba(255,255,255,.7);box-shadow:0 14px 34px rgba(36,32,26,.05)}.writer-queue-card{border:1px solid var(--plotline-line);border-radius:12px;padding:12px;background:rgba(255,255,255,.9)}.writer-queue-card h3{margin:0;font-size:1rem}.writer-queue-card p{margin:8px 0 0;color:var(--plotline-muted)}.writer-queue-title{display:flex;align-items:start;justify-content:space-between;gap:12px}.writer-kpi{display:block;color:var(--plotline-accent);font-size:2.2rem;line-height:1}.export-action-row{margin:-8px 0 18px}.dynamics-timeline{position:relative;min-height:128px;border:1px solid var(--plotline-line);border-radius:14px;background:linear-gradient(180deg,rgba(47,111,99,.07),rgba(255,255,255,.84));overflow:hidden}.dynamics-timeline::before{content:"";position:absolute;left:12px;right:12px;top:64px;height:1px;background:rgba(36,32,26,.18)}.dynamics-marker{position:absolute;bottom:18px;width:12px;height:86px;transform:translateX(-50%);display:flex;align-items:end;justify-content:center}.dynamics-marker span{display:block;width:8px;min-height:12px;max-height:82px;border-radius:999px;background:var(--plotline-accent);box-shadow:0 8px 20px rgba(47,111,99,.22)}.dynamics-marker.pov span{background:#8a4b2f}.dynamics-timeline.relationship .dynamics-marker span{background:#7c5fb0}.scenario-banner{display:flex;justify-content:space-between;gap:18px;align-items:flex-start;border:1px solid rgba(103,80,164,.22);border-radius:12px;padding:16px;margin-bottom:16px;background:linear-gradient(135deg,rgba(103,80,164,.1),rgba(255,255,255,.86));box-shadow:0 12px 28px rgba(36,32,26,.08)}.scenario-banner h1{margin:0 0 4px}.scenario-banner p{margin:0;color:var(--plotline-muted)}.scenario-card{border-color:rgba(103,80,164,.18)}.scenario-warning-strip{display:flex;gap:10px;align-items:center;border:1px solid var(--plotline-line);border-radius:10px;padding:10px 12px;margin-bottom:14px;background:rgba(255,255,255,.76);color:var(--plotline-muted)}.scenario-warning-strip strong{color:var(--plotline-ink)}.scenario-board{border:1px solid var(--plotline-line);border-radius:12px;padding:12px;background:rgba(247,245,240,.74);overflow:hidden;margin-bottom:18px}.scenario-scroll{display:flex;gap:14px;overflow-x:auto;padding-bottom:8px}.scenario-chapter{min-width:360px;max-width:520px;border:1px solid rgba(82,75,65,.14);border-radius:10px;background:rgba(255,255,255,.86)}.scenario-chapter header{display:grid;gap:2px;border-bottom:1px solid var(--plotline-line);padding:10px 12px}.scenario-chapter header span{color:var(--plotline-muted);font-size:.78rem;font-weight:800;text-transform:uppercase}.scenario-scene-row{display:grid;gap:10px;padding:10px}.scenario-scene-card{display:grid;gap:8px;border:1px solid rgba(82,75,65,.12);border-radius:9px;padding:10px;background:#fff}.scenario-scene-title{display:grid;gap:2px}.scenario-scene-title span,.scenario-mini-data{color:var(--plotline-muted);font-size:.78rem}.scenario-mini-data{display:grid;gap:2px}.scenario-move-actions,.scenario-chapter-form,.scenario-compare-list article{display:flex;gap:8px;flex-wrap:wrap;align-items:center}.scenario-chapter-form select{min-width:160px;width:auto}.scenario-compare-list{display:grid;gap:10px}.scenario-compare-list article{justify-content:space-between;border:1px solid var(--plotline-line);border-radius:9px;padding:10px;background:rgba(255,255,255,.82)}.danger-zone{border-color:rgba(163,61,61,.24)}.archive-filter-form{align-items:end}.archive-item-list{display:grid;gap:10px}.archive-item-card{display:flex;justify-content:space-between;gap:14px;align-items:center;border:1px solid var(--plotline-line);border-radius:10px;padding:12px;background:rgba(255,255,255,.82)}.archive-actions{display:flex;flex-wrap:wrap;gap:8px;align-items:center;justify-items:end}.delete-forever-form{display:inline-flex;margin:0}.archive-item-card h3{margin:4px 0}.archived-badge{display:inline-flex;border:1px solid rgba(82,75,65,.16);border-radius:999px;padding:2px 8px;color:var(--plotline-muted);font-size:.72rem;font-weight:800;text-transform:uppercase;background:rgba(247,245,240,.86)}.restore-button{white-space:nowrap}.archive-button-form{display:inline-flex;align-items:center;margin:0}.acceptance-summary-grid{display:grid;grid-template-columns:repeat(3,minmax(160px,1fr));gap:12px;margin-bottom:16px}.acceptance-summary{display:grid;gap:4px;padding:16px}.acceptance-summary strong{font-size:2rem;line-height:1}.acceptance-summary.pass{border-left:5px solid #4d7654}.acceptance-summary.review{border-left:5px solid #b8762b}.acceptance-summary.blocked{border-left:5px solid #963f36}.acceptance-check-list{display:grid;gap:14px}.acceptance-area{border:1px solid var(--plotline-line);border-radius:10px;padding:12px;background:rgba(255,255,255,.62)}.acceptance-area h3{margin:0 0 10px;font-size:1.05rem}.acceptance-check-items{display:grid;gap:8px}.acceptance-check-item{display:grid;grid-template-columns:92px minmax(0,1fr);gap:10px;align-items:start;border:1px solid rgba(82,75,65,.12);border-radius:8px;padding:10px;background:rgba(255,255,255,.74)}.acceptance-check-item p{margin:2px 0 0;color:var(--plotline-muted)}.acceptance-status{display:inline-flex;justify-content:center;width:fit-content;min-width:74px;border-radius:999px;padding:3px 9px;font-size:.72rem;font-weight:900;text-transform:uppercase}.acceptance-check-item.pass .acceptance-status{color:#24512b;background:#e6f4e7}.acceptance-check-item.review .acceptance-status{color:#7b4b13;background:#fbecd3}.acceptance-check-item.blocked .acceptance-status{color:#7a2222;background:#fff0f0}.plotline-confirm-modal .modal-title{color:var(--plotline-ink)}.plotline-confirm-modal .modal-body p{white-space:pre-line}.delete-confirm-field{border:1px solid rgba(163,61,61,.22);border-radius:8px;padding:12px;background:rgba(255,247,244,.7)}@media print{header,.breadcrumb-trail,.context-header,.button-row,.story-bible-nav,.inspector-quick-nav{display:none!important}.plotline-shell{max-width:none;padding:0}}@media(max-width:760px){.plotline-shell{padding-left:14px;padding-right:14px}.page-heading{display:block}.page-heading .button-row,.timeline-filter{margin-top:14px}.timeline-filter{align-items:stretch;flex-direction:column}.timeline-navigation-card{grid-template-areas:"copy" "actions";grid-template-columns:1fr}.timeline-navigation-card-icon{display:none}.timeline-navigation-card-actions{justify-content:center}.story-bible-search,.story-bible-section-heading{align-items:stretch;flex-direction:column}.story-bible-scene-summary,.attention-list article{grid-template-columns:1fr}.writer-dashboard-grid{grid-template-columns:1fr}.writer-checklist-row,.writer-add-inline{grid-template-columns:1fr}.trial-status-panel--signup,.trial-status-panel__heading,.trial-dashboard-banner{align-items:stretch;flex-direction:column}.trial-dashboard-banner__actions,.trial-dashboard-banner__actions .btn,.trial-status-panel--signup .btn{width:100%}.attention-list p{grid-column:auto}}@media(max-width:900px){.workspace-layout,.workspace-layout.inspector-drawer-open{grid-template-columns:1fr;gap:14px}.timeline-inspector-resizer{display:none}.scene-inspector-panel{position:static;max-height:none;overflow:visible}.scene-inspector-body{max-height:none;overflow:visible}}@media(max-width:1100px){.metric-graph-row{grid-template-columns:1fr}.health-kpi-grid,.analytics-grid-two,.analytics-grid-three{grid-template-columns:1fr}.analytics-metric-row{grid-template-columns:1fr}.analytics-metric-label{border-right:0}}.floor-plan-list{display:grid;gap:12px}.floor-plan-list-item{align-items:center;border:1px solid var(--border-color,#d8ded9);border-radius:8px;display:flex;justify-content:space-between;gap:16px;padding:14px}.floor-plan-list-item h2{font-size:1.05rem;margin:0 0 4px}.floor-plan-list-item p{margin:0}.floor-plan-tools{display:grid;gap:14px}.floor-plan-meta-wide{max-width:none}.floor-plan-tabs{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:12px}.floor-plan-tab{background:var(--panel-bg,#fff);border:1px solid var(--border-color,#d8ded9);border-radius:999px;color:inherit;padding:6px 12px}.floor-plan-tab.active{background:var(--bs-primary,#2f6f63);border-color:var(--bs-primary,#2f6f63);color:#fff}.floor-plan-layout{display:grid;gap:16px;grid-template-columns:minmax(0,1fr) minmax(320px,360px)}.floor-plan-editor--occupancy .floor-plan-layout{grid-template-columns:minmax(0,1fr)}.floor-plan-editor-toolbar{background:rgba(255,255,255,.92);border:1px solid var(--border-color,#d8ded9);border-radius:8px;display:grid;gap:10px;margin-bottom:12px;padding:10px 12px;position:sticky;top:10px;z-index:20}.floor-plan-toolbar-main,.floor-plan-toolbar-floor-group,.floor-plan-toolbar-control-group,.floor-plan-toolbar-action-group,.floor-plan-occupancy-scene-row{align-items:center;display:flex;flex-wrap:wrap;gap:10px}.floor-plan-toolbar-main{justify-content:space-between}.floor-plan-toolbar-floor-group{flex:1 1 420px;min-width:min(100%,320px)}.floor-plan-active-floor{display:grid;gap:2px}.floor-plan-toolbar-control-group{flex:0 1 auto}.floor-plan-toolbar-action-group{flex:1 1 360px;justify-content:flex-end}.floor-plan-occupancy-scene-row{border-top:1px solid rgba(47,111,99,.12);padding-top:9px}.floor-plan-occupancy-scene-row[hidden]{display:none}.floor-plan-occupancy-scene-row .floor-plan-reference-control{flex:1 1 320px;min-width:min(100%,320px)}.floor-plan-occupancy-scene-row .form-select{width:100%}.floor-plan-occupancy-warning-panel{background:rgba(47,111,99,.05);border:1px solid rgba(47,111,99,.16);border-radius:8px;color:var(--plotline-ink,#1e252b);flex:1 1 100%;font-size:.82rem;padding:.55rem .7rem}.floor-plan-occupancy-warning-panel strong{display:block;font-size:.78rem;margin-bottom:.25rem;text-transform:uppercase}.floor-plan-occupancy-warning-panel p,.floor-plan-occupancy-warning-panel ul{margin:0}.floor-plan-occupancy-warning-panel ul{display:grid;gap:.25rem;list-style:none;padding:0}.floor-plan-occupancy-warning,.floor-plan-occupancy-warning-empty{border-radius:6px;font-weight:700;padding:.32rem .45rem}.floor-plan-occupancy-warning-empty{background:rgba(47,111,99,.08);color:var(--plotline-accent-dark,#22534a)}.floor-plan-occupancy-warning--warning{background:rgba(251,236,211,.78);color:#7b4b12}.floor-plan-occupancy-warning--info{background:rgba(233,243,248,.86);color:#245b78}.floor-plan-occupancy-warning[hidden],.floor-plan-occupancy-warning-empty[hidden]{display:none}.floor-plan-editor-toolbar .muted{display:block;font-size:.76rem;line-height:1.1}.floor-plan-toolbar-check,.floor-plan-reference-control{align-items:center;color:var(--muted-color,#6b756f);display:inline-flex;font-size:.82rem;font-weight:700;gap:6px}.floor-plan-reference-control{align-items:flex-start;flex-direction:column;gap:2px}.floor-plan-reference-control .form-select{min-width:180px}.floor-plan-save-status{border:1px solid rgba(47,111,99,.2);border-radius:999px;color:var(--plotline-accent-dark,#22534a);background:rgba(47,111,99,.08);font-size:.78rem;font-weight:800;padding:4px 9px}.floor-plan-save-status[data-save-state="dirty"]{border-color:rgba(184,118,43,.32);color:#7b4b12;background:rgba(251,236,211,.72)}.floor-plan-save-status[data-save-state="saving"]{border-color:rgba(51,117,155,.3);color:#245b78;background:rgba(233,243,248,.82)}.floor-plan-save-status[data-save-state="failed"]{border-color:rgba(163,61,61,.32);color:#8a3434;background:rgba(255,232,232,.9)}.floor-plan-floor{display:none}.floor-plan-floor.active{display:block}.floor-plan-stage{min-width:0}.floor-plan-grid-wrap{max-width:100%;max-height:calc(100vh - 250px);min-height:min(58vh,520px);overflow:auto;padding-bottom:8px}.floor-plan-grid{--cell-size:34px;background:linear-gradient(to right,rgba(93,111,101,.18) 1px,transparent 1px),linear-gradient(to bottom,rgba(93,111,101,.18) 1px,transparent 1px),var(--panel-bg,#fff);background-size:var(--cell-size) var(--cell-size),var(--cell-size) var(--cell-size),auto;border:1px solid var(--border-color,#d8ded9);border-radius:8px;height:calc(var(--grid-height)*var(--cell-size));min-width:calc(var(--grid-width)*var(--cell-size));position:relative;width:calc(var(--grid-width)*var(--cell-size))}.floor-plan-coordinate-label{color:rgba(33,61,55,.42);font-size:.62rem;font-weight:800;line-height:1;pointer-events:none;position:absolute;text-shadow:0 1px 0 rgba(255,255,255,.7);user-select:none;z-index:5}.floor-plan-coordinate-label--column{left:calc(var(--coord-x)*var(--cell-size) + 4px);top:3px}.floor-plan-coordinate-label--row{left:4px;top:calc(var(--coord-y)*var(--cell-size) + 4px)}.floor-plan-reference-overlay{inset:0;pointer-events:none;position:absolute;z-index:1}.floor-plan-reference-block{align-items:center;background:rgba(47,111,99,.08);border:1px dashed rgba(47,111,99,.34);border-radius:2px;color:rgba(27,55,49,.46);display:flex;font-size:.62rem;font-weight:800;height:calc(var(--h)*var(--cell-size));justify-content:center;left:calc(var(--x)*var(--cell-size));line-height:1.05;overflow:hidden;padding:3px;position:absolute;text-align:center;top:calc(var(--y)*var(--cell-size));width:calc(var(--w)*var(--cell-size))}.floor-plan-reference-warning{background:rgba(251,236,211,.92);border:1px solid rgba(184,118,43,.34);border-radius:999px;color:#7b4b12;font-size:.76rem;font-weight:800;left:10px;padding:4px 10px;pointer-events:none;position:absolute;top:10px;z-index:6}.floor-plan-background-image{height:auto;left:0;max-width:none;opacity:var(--bg-opacity,.35);pointer-events:none;position:absolute;top:0;transform:translate(var(--bg-offset-x,0),var(--bg-offset-y,0)) scale(var(--bg-scale,1));transform-origin:top left;user-select:none;width:100%;z-index:0}.floor-plan-background-image.is-locked{pointer-events:none}.floor-plan-block{align-items:center;--floor-plan-wall-color:rgba(44,84,75,.55);border:2px solid transparent;border-radius:2px;color:#12332c;cursor:grab;display:flex;font-size:.72rem;font-weight:700;height:calc(var(--h)*var(--cell-size));justify-content:center;left:calc(var(--x)*var(--cell-size));line-height:1.08;overflow:hidden;padding:4px;position:absolute;text-align:center;top:calc(var(--y)*var(--cell-size));touch-action:none;width:calc(var(--w)*var(--cell-size));z-index:2}.floor-plan-wall-segment{background:var(--floor-plan-wall-color);pointer-events:none;position:absolute;z-index:2}.floor-plan-wall-segment--north,.floor-plan-wall-segment--south{height:2px;left:var(--wall-start);width:var(--wall-length)}.floor-plan-wall-segment--north{top:0}.floor-plan-wall-segment--south{bottom:0}.floor-plan-wall-segment--east,.floor-plan-wall-segment--west{height:var(--wall-length);top:var(--wall-start);width:2px}.floor-plan-wall-segment--east{right:0}.floor-plan-wall-segment--west{left:0}.floor-plan-block-label{display:-webkit-box;max-width:100%;overflow:hidden;overflow-wrap:normal;text-overflow:ellipsis;-webkit-box-orient:vertical;-webkit-line-clamp:1}.floor-plan-block[style*="--h:2"] .floor-plan-block-label,.floor-plan-block[style*="--h:3"] .floor-plan-block-label,.floor-plan-block[style*="--h:4"] .floor-plan-block-label,.floor-plan-block[style*="--h:5"] .floor-plan-block-label,.floor-plan-block[style*="--h:6"] .floor-plan-block-label,.floor-plan-block[style*="--h:7"] .floor-plan-block-label,.floor-plan-block[style*="--h:8"] .floor-plan-block-label{-webkit-line-clamp:2}.floor-plan-block.selected{box-shadow:0 0 0 3px rgba(47,111,99,.28);outline:2px solid var(--bs-primary,#2f6f63);z-index:3}.floor-plan-block.overlap{border-color:#b45544;box-shadow:inset 0 0 0 2px rgba(180,85,68,.18)}.floor-plan-block.is-hidden-location{background-image:repeating-linear-gradient(135deg,rgba(18,51,44,.08) 0,rgba(18,51,44,.08) 3px,transparent 3px,transparent 9px);box-shadow:inset 0 0 0 1px rgba(43,54,49,.18)}.floor-plan-block.is-hidden-location.selected{box-shadow:inset 0 0 0 1px rgba(43,54,49,.18),0 0 0 3px rgba(47,111,99,.28)}.floor-plan-block.is-hidden-location.overlap{box-shadow:inset 0 0 0 2px rgba(180,85,68,.18),inset 0 0 0 1px rgba(43,54,49,.18)}.floor-plan-secret-route{border-top:2px dashed rgba(69,55,42,.58);height:0;left:calc(var(--route-x,0)*var(--cell-size));opacity:.72;pointer-events:none;position:absolute;top:calc(var(--route-y,0)*var(--cell-size));transform:rotate(var(--route-angle,0));transform-origin:0 50%;width:calc(var(--route-length,0)*var(--cell-size));z-index:3}.floor-plan-secret-route::after{background:rgba(255,250,242,.9);border:1px solid rgba(69,55,42,.5);border-radius:50%;content:"";height:7px;left:50%;position:absolute;top:-5px;transform:translateX(-50%);width:7px}.floor-plan-transition-marker{align-items:center;--transition-marker-ink:#12332c;--transition-marker-window:#246f9f;--transition-marker-blocked:#9b342b;background:rgba(255,250,242,.98);border:1px solid rgba(47,111,99,.55);border-radius:50%;box-shadow:0 2px 6px rgba(31,37,34,.16);color:var(--transition-marker-ink);display:flex;font-size:.72rem;font-weight:900;height:21px;justify-content:center;left:calc(var(--transition-x,0)*var(--cell-size));line-height:1;pointer-events:none;position:absolute;top:calc(var(--transition-y,0)*var(--cell-size));transform:translate(-50%,-50%);width:21px;z-index:4}.floor-plan-transition-marker svg{display:block;height:21px;overflow:visible;width:21px}.floor-plan-transition-marker.is-vertical svg{transform:rotate(90deg)}.floor-plan-transition-marker .marker-line,.floor-plan-transition-marker .marker-arc,.floor-plan-transition-marker .marker-window,.floor-plan-transition-marker .marker-blocked{fill:none;stroke:currentColor;stroke-linecap:round;stroke-linejoin:round;stroke-width:1.7}.floor-plan-transition-marker .marker-arc{stroke-width:1.35}.floor-plan-transition-marker .marker-window{stroke:var(--transition-marker-window)}.floor-plan-transition-marker .marker-dotted{opacity:.72;stroke-dasharray:1.4 2}.floor-plan-transition-marker .marker-blocked{stroke:var(--transition-marker-blocked);stroke-width:1.8}.floor-plan-transition-marker .marker-strong{stroke-width:2}.floor-plan-transition-marker .marker-track{opacity:.72}.floor-plan-transition-marker--window{background:rgba(239,249,255,.98);border-color:rgba(36,111,159,.48)}.floor-plan-transition-marker--sliding-door{background:rgba(248,252,249,.98);border-color:rgba(47,111,99,.58)}.floor-plan-transition-marker--french-door{background:rgba(255,252,246,.98);border-color:rgba(119,86,45,.5)}.floor-plan-transition-marker--secret-door{background:rgba(255,250,242,.88);border-style:dashed}.floor-plan-transition-marker--ladder{background:rgba(246,248,245,.98);border-color:rgba(77,91,67,.55)}.floor-plan-transition-marker--blocked-door{background:rgba(255,244,241,.98);border-color:rgba(155,52,43,.52)}.floor-plan-transition-marker--exterior-door{border-width:2px}.floor-plan-transition-marker.is-shared-edge{background:rgba(255,255,255,.98);border-color:rgba(47,111,99,.72)}.floor-plan-transition-marker--window.is-shared-edge{background:rgba(239,249,255,.98);border-color:rgba(36,111,159,.58)}.floor-plan-transition-marker--blocked-door.is-shared-edge{background:rgba(255,244,241,.98);border-color:rgba(155,52,43,.6)}.visual-card-heading{align-items:flex-start;display:flex;gap:12px}.visual-card-heading>div{min-width:0}.visual-avatar{align-items:center;aspect-ratio:1;background:linear-gradient(135deg,rgba(47,111,99,.16),rgba(212,154,98,.16));border:1px solid rgba(47,111,99,.22);border-radius:999px;color:var(--plotline-accent-dark,#22534a);display:inline-flex;flex:0 0 auto;font-weight:900;justify-content:center;letter-spacing:.02em;overflow:hidden;text-transform:uppercase}.visual-avatar img{height:100%;object-fit:cover;width:100%}.visual-avatar--sm{font-size:.72rem;width:32px}.visual-avatar--md{font-size:.9rem;width:48px}.visual-avatar--lg{font-size:1.3rem;width:96px}.visual-avatar--xl{font-size:1.6rem;width:128px}.visual-image-editor{align-items:center;background:rgba(47,111,99,.05);border:1px solid rgba(47,111,99,.14);border-radius:8px;display:flex;gap:18px;padding:14px}.visual-image-editor__controls{flex:1 1 auto;min-width:220px}.floor-plan-block--room{background:#d9eee7}.floor-plan-block--corridor{background:#e7e2f4}.floor-plan-block--openspace{background:#e5efd4}.floor-plan-block--exterior{background:#d9ecf3}.floor-plan-block--other{background:#ece9e1}.floor-plan-resize-handle{border-bottom:10px solid rgba(18,51,44,.45);border-left:10px solid transparent;bottom:4px;height:0;position:absolute;right:4px;width:0}.floor-plan-side-panel{align-self:start;position:sticky;top:82px}.floor-plan-side-panel h2{font-size:1.05rem;margin-bottom:8px}.floor-plan-side-panel h3{font-size:.92rem;margin:0 0 8px}.floor-plan-toolbox{background:var(--panel-bg,#fff);border:1px solid var(--border-color,#d8ded9);border-radius:8px;display:grid;grid-template-rows:auto minmax(0,1fr);max-height:calc(100vh - 250px);min-height:min(58vh,520px);overflow:hidden}.floor-plan-toolbox-tabs{border-bottom:1px solid var(--border-color,#d8ded9);display:flex;flex-wrap:wrap;gap:0}.floor-plan-toolbox-tab{background:transparent;border:0;border-right:1px solid var(--border-color,#d8ded9);border-bottom:1px solid var(--border-color,#d8ded9);color:inherit;flex:1 1 118px;font-size:.82rem;font-weight:800;min-width:112px;padding:10px 8px}.floor-plan-toolbox-tab:last-child,.floor-plan-toolbox-tab.active:last-child{border-right:0}.floor-plan-toolbox-tab.active{background:rgba(47,111,99,.1);border-bottom-color:var(--plotline-accent,#2f6f63);color:var(--plotline-accent-dark,#22534a)}.floor-plan-toolbox-body{min-height:0;overflow:auto}.floor-plan-tool-card{background:var(--panel-bg,#fff);border:1px solid var(--border-color,#d8ded9);border-radius:8px;padding:14px}.floor-plan-toolbox .floor-plan-tool-card{background:transparent;border:0;border-radius:0}.floor-plan-tool-card[hidden]{display:none}.floor-plan-tool-card p{margin-bottom:10px}.floor-plan-tool-subsection{border-top:1px solid var(--border-color,#d8ded9);margin-top:12px;padding-top:12px}.floor-plan-tool-subsection:first-of-type{border-top:0;margin-top:0;padding-top:0}.floor-plan-background-file{border:1px solid rgba(47,111,99,.16);border-radius:6px;font-size:.86rem;padding:8px 10px}.floor-plan-background-range{align-items:center;display:grid;gap:10px;grid-template-columns:minmax(0,1fr) 44px}.floor-plan-background-range span{color:var(--muted-text,#5d6f65);font-size:.8rem;font-variant-numeric:tabular-nums;text-align:right}.floor-plan-transition-list{display:grid;gap:8px}.floor-plan-transition-item{border:1px solid rgba(47,111,99,.14);border-radius:6px;display:grid;gap:8px;padding:8px}.floor-plan-transition-item strong,.floor-plan-transition-item span{display:block;font-size:.84rem}.floor-plan-transition-item span{color:var(--muted-text,#5d6f65)}.scene-occupancy-form{display:grid;gap:.5rem}.scene-occupancy-status{justify-self:start;border-radius:999px;padding:.2rem .55rem;color:var(--plotline-muted);background:var(--plotline-soft);font-size:.78rem;font-weight:700}.scene-occupancy-status[data-save-state="saving"]{color:#7a4d08;background:#fff4d6}.scene-occupancy-status[data-save-state="failed"]{color:#842029;background:#f8d7da}.scene-occupancy-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:1rem}.scene-occupancy-grid h4{margin:0 0 .5rem;font-size:.95rem}.scene-occupancy-row{display:grid;grid-template-columns:minmax(8rem,.45fr) minmax(0,.55fr);align-items:center;gap:.5rem;margin-bottom:.45rem}.floor-plan-editor--occupancy .floor-plan-block{cursor:default;touch-action:auto}.floor-plan-editor--occupancy .floor-plan-resize-handle{display:none}.floor-plan-editor--occupancy .floor-plan-side-panel{display:none}.floor-plan-occupancy-tray{position:absolute;z-index:14;height:calc(var(--h)*var(--cell-size));left:calc(var(--x)*var(--cell-size));top:calc(var(--y)*var(--cell-size));width:calc(var(--w)*var(--cell-size));display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:.18rem;padding:0 0 .25rem;pointer-events:auto}.floor-plan-occupancy-tray[hidden]{display:none}.floor-plan-occupancy-token{display:grid;place-items:center;width:1.8rem;height:1.8rem;overflow:hidden;border:2px solid #fff;border-radius:999px;color:#fff;background:var(--plotline-accent);box-shadow:0 4px 12px rgba(30,37,43,.18);font-size:.68rem;font-weight:800}.floor-plan-occupancy-token img{width:100%;height:100%;object-fit:cover}.floor-plan-occupancy-token--asset{width:1.45rem;height:1.45rem;background:#805c15;font-size:.58rem}.floor-plan-occupancy-more{border-radius:999px;padding:.15rem .36rem;color:var(--plotline-ink);background:rgba(255,255,255,.92);box-shadow:0 4px 12px rgba(30,37,43,.12);font-size:.72rem;font-weight:800}.floor-plan-occupancy-message{align-self:start;background:rgba(255,255,255,.94);border:1px solid rgba(47,111,99,.18);border-radius:8px;box-shadow:0 6px 16px rgba(30,37,43,.08);color:var(--muted-color,#6b756f);font-size:.82rem;font-weight:700;grid-column:1/-1;grid-row:1;justify-self:center;margin-top:.55rem;max-width:min(92%,520px);padding:.45rem .7rem;position:relative;z-index:16}.floor-plan-occupancy-message[hidden]{display:none}.floor-plan-transition-accordion .accordion-item{background:transparent;border-color:var(--border-color,#d8ded9)}.floor-plan-transition-accordion .accordion-button{background:rgba(47,111,99,.06);color:inherit;font-size:.88rem;font-weight:800;padding:10px 12px}.floor-plan-transition-accordion .accordion-button:not(.collapsed){background:rgba(47,111,99,.12);color:var(--plotline-accent-dark,#22534a);box-shadow:inset 0 -1px 0 var(--border-color,#d8ded9)}.floor-plan-transition-accordion .accordion-body{padding:12px}.floor-plan-checkbox{align-items:center;display:inline-flex;gap:6px;font-weight:700;margin-bottom:4px}.floor-plan-choice-row{display:grid;gap:4px;margin-bottom:10px}.floor-plan-choice-row label{align-items:center;display:flex;gap:6px;font-size:.88rem}.floor-plan-overlap-warning{background:rgba(180,85,68,.12);border:1px solid rgba(180,85,68,.35);border-radius:6px;color:#8f3f31;margin-bottom:10px;padding:8px 10px}[data-bs-theme="dark"] .floor-plan-grid,.dark .floor-plan-grid{background:linear-gradient(to right,rgba(214,224,218,.12) 1px,transparent 1px),linear-gradient(to bottom,rgba(214,224,218,.12) 1px,transparent 1px),#15201d;background-size:var(--cell-size) var(--cell-size),var(--cell-size) var(--cell-size),auto}[data-bs-theme="dark"] .floor-plan-editor-toolbar,.dark .floor-plan-editor-toolbar,[data-bs-theme="dark"] .floor-plan-toolbox,.dark .floor-plan-toolbox,[data-bs-theme="dark"] .floor-plan-tool-card,.dark .floor-plan-tool-card{background:var(--panel-bg,#1f2522)}[data-bs-theme="dark"] .floor-plan-toolbox .floor-plan-tool-card,.dark .floor-plan-toolbox .floor-plan-tool-card{background:transparent}[data-bs-theme="dark"] .floor-plan-toolbox-tab.active,.dark .floor-plan-toolbox-tab.active{background:rgba(212,154,98,.16);color:var(--plotline-accent-dark,#f0c99d)}[data-bs-theme="dark"] .floor-plan-block,.dark .floor-plan-block{--floor-plan-wall-color:rgba(212,154,98,.6);color:#f1f6f3}[data-bs-theme="dark"] .floor-plan-block.is-hidden-location,.dark .floor-plan-block.is-hidden-location{background-image:repeating-linear-gradient(135deg,rgba(244,234,220,.09) 0,rgba(244,234,220,.09) 3px,transparent 3px,transparent 9px);box-shadow:inset 0 0 0 1px rgba(244,234,220,.2)}[data-bs-theme="dark"] .floor-plan-secret-route,.dark .floor-plan-secret-route{border-top-color:rgba(244,204,160,.58);opacity:.76}[data-bs-theme="dark"] .floor-plan-secret-route::after,.dark .floor-plan-secret-route::after{background:rgba(42,35,30,.95);border-color:rgba(244,204,160,.55)}[data-bs-theme="dark"] .floor-plan-coordinate-label,.dark .floor-plan-coordinate-label{color:rgba(244,234,220,.46);text-shadow:0 1px 0 rgba(0,0,0,.55)}[data-bs-theme="dark"] .floor-plan-reference-block,.dark .floor-plan-reference-block{background:rgba(131,199,242,.08);border-color:rgba(131,199,242,.32);color:rgba(244,234,220,.46)}[data-bs-theme="dark"] .floor-plan-reference-warning,.dark .floor-plan-reference-warning{background:rgba(84,57,25,.92);border-color:rgba(244,177,100,.32);color:#ffd9a5}[data-bs-theme="dark"] .floor-plan-transition-marker,.dark .floor-plan-transition-marker{--transition-marker-ink:#f4eadc;--transition-marker-window:#83c7f2;--transition-marker-blocked:#f08a78;background:rgba(42,35,30,.98);border-color:rgba(212,154,98,.6)}[data-bs-theme="dark"] .floor-plan-transition-marker.is-shared-edge,.dark .floor-plan-transition-marker.is-shared-edge{background:rgba(48,39,32,.98);border-color:rgba(212,154,98,.78)}[data-bs-theme="dark"] .floor-plan-transition-marker--window,.dark .floor-plan-transition-marker--window,[data-bs-theme="dark"] .floor-plan-transition-marker--window.is-shared-edge,.dark .floor-plan-transition-marker--window.is-shared-edge{background:rgba(24,45,58,.98);border-color:rgba(131,199,242,.66)}[data-bs-theme="dark"] .floor-plan-transition-marker--sliding-door,.dark .floor-plan-transition-marker--sliding-door,[data-bs-theme="dark"] .floor-plan-transition-marker--french-door,.dark .floor-plan-transition-marker--french-door,[data-bs-theme="dark"] .floor-plan-transition-marker--ladder,.dark .floor-plan-transition-marker--ladder{background:rgba(39,43,37,.98);border-color:rgba(212,154,98,.58)}[data-bs-theme="dark"] .floor-plan-transition-marker--blocked-door,.dark .floor-plan-transition-marker--blocked-door,[data-bs-theme="dark"] .floor-plan-transition-marker--blocked-door.is-shared-edge,.dark .floor-plan-transition-marker--blocked-door.is-shared-edge{background:rgba(58,33,28,.98);border-color:rgba(240,138,120,.66)}[data-bs-theme="dark"] .visual-avatar,.dark .visual-avatar{background:linear-gradient(135deg,rgba(131,199,242,.14),rgba(212,154,98,.18));border-color:rgba(244,234,220,.18);color:#f4eadc}[data-bs-theme="dark"] .visual-image-editor,.dark .visual-image-editor{background:rgba(244,234,220,.04);border-color:rgba(244,234,220,.12)}[data-bs-theme="dark"] .floor-plan-transition-item,.dark .floor-plan-transition-item{border-color:rgba(212,154,98,.22)}[data-bs-theme="dark"] .scene-occupancy-status,.dark .scene-occupancy-status{color:#d9c8b8;background:rgba(212,154,98,.12)}[data-bs-theme="dark"] .floor-plan-occupancy-token,.dark .floor-plan-occupancy-token{border-color:#1f2630;box-shadow:0 4px 12px rgba(0,0,0,.28)}[data-bs-theme="dark"] .floor-plan-occupancy-more,.dark .floor-plan-occupancy-more{color:#f1e7dd;background:rgba(31,38,48,.92)}[data-bs-theme="dark"] .floor-plan-occupancy-message,.dark .floor-plan-occupancy-message{background:rgba(31,38,48,.94);border-color:rgba(212,154,98,.24);color:#d9c8b8}[data-bs-theme="dark"] .floor-plan-occupancy-warning-panel,.dark .floor-plan-occupancy-warning-panel{background:rgba(244,234,220,.04);border-color:rgba(212,154,98,.2);color:#f1e7dd}[data-bs-theme="dark"] .floor-plan-occupancy-warning-empty,.dark .floor-plan-occupancy-warning-empty{background:rgba(47,111,99,.18);color:#b8e2d7}[data-bs-theme="dark"] .floor-plan-occupancy-warning--warning,.dark .floor-plan-occupancy-warning--warning{background:rgba(84,57,25,.92);color:#ffd9a5}[data-bs-theme="dark"] .floor-plan-occupancy-warning--info,.dark .floor-plan-occupancy-warning--info{background:rgba(24,45,58,.92);color:#b9dcf3}[data-bs-theme="dark"] .floor-plan-transition-accordion .accordion-item,.dark .floor-plan-transition-accordion .accordion-item{border-color:rgba(212,154,98,.22)}[data-bs-theme="dark"] .floor-plan-transition-accordion .accordion-button,.dark .floor-plan-transition-accordion .accordion-button{background:rgba(212,154,98,.08);color:#f4eadc}[data-bs-theme="dark"] .floor-plan-transition-accordion .accordion-button:not(.collapsed),.dark .floor-plan-transition-accordion .accordion-button:not(.collapsed){background:rgba(212,154,98,.16);color:var(--plotline-accent-dark,#f0c99d);box-shadow:inset 0 -1px 0 rgba(212,154,98,.22)}[data-bs-theme="dark"] .floor-plan-block--room,.dark .floor-plan-block--room{background:#29584f}[data-bs-theme="dark"] .floor-plan-block--corridor,.dark .floor-plan-block--corridor{background:#514876}[data-bs-theme="dark"] .floor-plan-block--openspace,.dark .floor-plan-block--openspace{background:#4f6133}[data-bs-theme="dark"] .floor-plan-block--exterior,.dark .floor-plan-block--exterior{background:#315d6f}[data-bs-theme="dark"] .floor-plan-block--other,.dark .floor-plan-block--other{background:#5b564c}@media(max-width:1100px){.floor-plan-layout,.floor-plan-editor-toolbar{grid-template-columns:1fr}.floor-plan-grid-wrap{max-height:62vh}.floor-plan-side-panel{position:static}.floor-plan-toolbox{max-height:none}} \ No newline at end of file diff --git a/PlotLine/wwwroot/js/site.js b/PlotLine/wwwroot/js/site.js index 89be3d2..9831a94 100644 --- a/PlotLine/wwwroot/js/site.js +++ b/PlotLine/wwwroot/js/site.js @@ -63,6 +63,129 @@ }); })(); +(() => { + const toggle = document.querySelector("[data-word-companion-follow-toggle]"); + if (!toggle || !window.signalR) { + return; + } + + const storageKey = "plotdirector.followWordCompanion"; + const unsafePathPrefixes = [ + "/pricing", + "/about", + "/contact", + "/privacy", + "/terms", + "/admin", + "/billing", + "/account", + "/login", + "/register", + "/feature-requests/admin", + "/featurerequests/admin", + "/manageaccount" + ]; + let lastSceneId = null; + let lastCharactersProjectId = null; + + const readEnabled = () => { + try { + return localStorage.getItem(storageKey) === "true"; + } catch { + return false; + } + }; + + const writeEnabled = (value) => { + try { + localStorage.setItem(storageKey, value ? "true" : "false"); + } catch { + // Follow mode is optional, so storage failures should not interrupt the app. + } + }; + + const applyToggle = (enabled) => { + toggle.setAttribute("aria-pressed", String(enabled)); + toggle.classList.toggle("active", enabled); + toggle.title = enabled + ? "PlotDirector will follow the current Word Companion scene." + : "Enable this to let PlotDirector follow the current Word Companion scene."; + }; + + const isSafeCurrentPage = () => { + const path = window.location.pathname.toLowerCase(); + if (path === "/" || path === "") { + return false; + } + + return !unsafePathPrefixes.some((prefix) => path === prefix || path.startsWith(`${prefix}/`)); + }; + + const safeRelativeUrl = (url, expectedPrefix) => { + if (typeof url !== "string" || !url.startsWith(expectedPrefix)) { + return ""; + } + + try { + const parsed = new URL(url, window.location.origin); + return parsed.origin === window.location.origin ? `${parsed.pathname}${parsed.search}${parsed.hash}` : ""; + } catch { + return ""; + } + }; + + const navigateIfAllowed = (url) => { + if (!readEnabled() || !isSafeCurrentPage() || !url) { + return; + } + + const current = `${window.location.pathname}${window.location.search}${window.location.hash}`; + if (current === url) { + return; + } + + window.location.assign(url); + }; + + applyToggle(readEnabled()); + toggle.addEventListener("click", () => { + const enabled = !readEnabled(); + writeEnabled(enabled); + applyToggle(enabled); + }); + + const connection = new signalR.HubConnectionBuilder() + .withUrl("/hubs/word-companion-follow") + .withAutomaticReconnect() + .build(); + + connection.on("wordCompanionSceneChanged", (payload) => { + const sceneId = Number.parseInt(payload?.sceneId || payload?.SceneId || "", 10); + if (!Number.isInteger(sceneId) || sceneId <= 0 || sceneId === lastSceneId) { + return; + } + + lastSceneId = sceneId; + const sceneUrl = safeRelativeUrl(payload?.sceneUrl || payload?.SceneUrl || "", "/Scenes/Details/"); + navigateIfAllowed(sceneUrl); + }); + + connection.on("wordCompanionCharactersCreated", (payload) => { + const projectId = Number.parseInt(payload?.projectId || payload?.ProjectId || "", 10); + if (!Number.isInteger(projectId) || projectId <= 0 || projectId === lastCharactersProjectId) { + return; + } + + lastCharactersProjectId = projectId; + const charactersUrl = safeRelativeUrl(payload?.charactersUrl || payload?.CharactersUrl || "", "/Characters"); + navigateIfAllowed(charactersUrl); + }); + + connection.start().catch((error) => { + console.debug("Word Companion follow connection unavailable.", error); + }); +})(); + (() => { const inspectorRoots = document.querySelectorAll(".scene-inspector-root"); if (!inspectorRoots.length) { diff --git a/PlotLine/wwwroot/js/site.min.js b/PlotLine/wwwroot/js/site.min.js index 90527cf..8f9c5db 100644 --- a/PlotLine/wwwroot/js/site.min.js +++ b/PlotLine/wwwroot/js/site.min.js @@ -1 +1 @@ -(()=>{const e="plotline.theme",t=document.querySelectorAll("[data-theme-choice]"),a=a=>{const n="dark"===a?"dark":"light";document.documentElement.dataset.theme=n,document.documentElement.dataset.bsTheme=n,(t=>{try{localStorage.setItem(e,t)}catch{}})(n),t.forEach(e=>{const t=e.dataset.themeChoice===n;e.classList.toggle("active",t),e.setAttribute("aria-pressed",String(t))})};t.forEach(e=>{e.addEventListener("click",()=>a(e.dataset.themeChoice))}),a((()=>{try{return localStorage.getItem(e)}catch{return null}})()||"light")})(),(()=>{const e=document.querySelector("[data-trial-banner]");if(!e)return;const t=`plotline.trialBanner.dismissed.${e.dataset.trialBannerKey||"current"}`;try{if("true"===localStorage.getItem(t))return void(e.hidden=!0)}catch{}e.querySelector("[data-trial-banner-dismiss]")?.addEventListener("click",()=>{e.hidden=!0;try{localStorage.setItem(t,"true")}catch{}})})(),(()=>{const e=document.querySelectorAll(".scene-inspector-root");if(!e.length)return;e.forEach(e=>{e.addEventListener("submit",e=>{const t=e.target;if(!(t instanceof HTMLFormElement))return;let a=t.querySelector("input[name='ReturnUrl']");a||(a=document.createElement("input"),a.type="hidden",a.name="ReturnUrl",t.appendChild(a)),a.value=`${window.location.pathname}${window.location.search}${window.location.hash}`},!0)})})(),(()=>{const e=document.querySelectorAll(".scene-inspector-root");if(!e.length)return;const t=(e,t,a)=>{const n=e.querySelector("[data-scene-occupancy-status]");n&&(n.textContent=t,n.dataset.saveState=a||"")},a=(e,t)=>{const a=document.createElement("div");a.innerHTML=t;const n=a.querySelector("[data-scene-occupancy-form]");if(n){e.replaceWith(n);const t=n.closest(".scene-inspector-root")?.querySelector(".scene-inspector-form"),a=t?.querySelector("[name='FloorPlanID']"),r=t?.querySelector("[name='InitialFloorPlanFloorID']"),o=n.querySelector("[name='FloorPlanID']"),s=n.querySelector("[name='InitialFloorPlanFloorID']");a&&o&&(a.value=o.value),r&&s&&(r.value=s.value)}};e.forEach(e=>{e.addEventListener("change",async e=>{const n=e.target.closest?.("[data-occupancy-plan-select]");if(!n)return;const r=n.closest("[data-scene-occupancy-form]"),o=r?.querySelector("[name='SceneID']")?.value,s=r?.dataset.editorUrl;if(!r||!o||!s)return;t(r,"Loading...","saving");const i=new URL(s,window.location.origin);i.searchParams.set("sceneId",o),n.value&&i.searchParams.set("floorPlanId",n.value);try{const e=await fetch(i,{headers:{"X-Requested-With":"XMLHttpRequest"}});if(!e.ok)throw new Error("The occupancy editor could not be refreshed.");a(r,await e.text())}catch(e){t(r,e.message||"Load failed","failed")}}),e.addEventListener("submit",async e=>{const n=e.target.closest?.("[data-scene-occupancy-form]");if(n){e.preventDefault(),t(n,"Saving...","saving");try{const e=await fetch(n.action,{method:"POST",body:new FormData(n),headers:{"X-Requested-With":"XMLHttpRequest"}});if(!e.ok){let t="Save failed";if((e.headers.get("content-type")||"").includes("application/json")){t=(await e.json()).message||t}throw new Error(t)}a(n,await e.text())}catch(e){t(n,e.message||"Save failed","failed")}}})})})(),(()=>{const e=document.getElementById("plotlineConfirmModal"),t=e&&window.bootstrap?new bootstrap.Modal(e):null,a=e?.querySelector("#plotlineConfirmModalTitle"),n=e?.querySelector("#plotlineConfirmModalMessage"),r=e?.querySelector("[data-confirm-submit]"),o=e?.querySelector("[data-delete-confirm-field]"),s=e?.querySelector("[data-delete-confirm-input]");let i=null,l=null;e?.addEventListener("hidden.bs.modal",()=>{i=null,l=null,s&&(s.value=""),o?.classList.add("d-none"),r?.removeAttribute("disabled")}),s?.addEventListener("input",()=>{"true"===i?.dataset.requireDeleteText&&r&&(r.disabled="DELETE"!==s.value.trim())}),r?.addEventListener("click",()=>{if(i){if("true"===i.dataset.requireDeleteText){const e=i.querySelector("[data-delete-confirm-target], [name='confirmationText']");e&&(e.value=s?.value.trim()||"")}i.dataset.confirmed="true",t?.hide(),i.requestSubmit&&l?i.requestSubmit(l):i.requestSubmit?i.requestSubmit():i.submit()}}),document.addEventListener("submit",c=>{const d=c.target;if(!(d instanceof HTMLFormElement)||"true"===d.dataset.confirmed||"true"===d.dataset.confirmSkip||"true"===d.dataset.noDeleteConfirm)return;const p=d.dataset.confirmMessage,u=c.submitter instanceof HTMLElement?c.submitter:d.querySelector("button[type='submit']"),m=u?.textContent||"",h=d.getAttribute("action")||"",g=/restore/i.test(m)||/\/restore\b/i.test(h),f=/delete forever/i.test(m)||/\/deleteforever\b/i.test(h),v=!g&&!f&&(/archive/i.test(m)||/\/archive\b/i.test(h)),y=!f&&/(delete|remove)/i.test(m);if(!(p||v||g||y||f))return;const w=p||(v?"Archive this item?\n\nThis will hide it from active lists and timelines, but the data will be kept and can be restored later.":g?"Restore this item?\n\nThis will return it to active lists and timelines where applicable.":f?"Permanently delete this item?\n\nThis cannot be undone. Any linked planning data may also be removed or become unavailable. Only continue if you are certain.":"Remove this item?\n\nThis removes the link or supporting record. Major story items are archived instead of permanently deleted.");if(!(t&&e&&a&&n&&r))return;c.preventDefault();const S=(e=>{const t=e.split(/\n\s*\n/);return{title:t.shift()?.trim()||"Confirm action",body:t.join("\n\n").trim()}})(w);i=d,l=u,a.textContent=d.dataset.confirmTitle||S.title,n.textContent=d.dataset.confirmBody||S.body,r.textContent=d.dataset.confirmButtonText||m.trim()||"Confirm",r.className=`btn ${d.dataset.confirmButtonClass||(g?"btn-primary":"btn-danger")}`;const L="true"===d.dataset.requireDeleteText||f;o?.classList.toggle("d-none",!L),L&&r&&(r.disabled=!0,s?.focus()),t.show(),L&&window.setTimeout(()=>s?.focus(),200)})})(),(()=>{const e=document.querySelectorAll("[data-help-icon]");if(!e.length||!window.bootstrap)return;const t=new Map;let a=null;const n=e=>e.querySelector("[data-help-tooltip]")||e,r=e=>bootstrap.Tooltip.getInstance(n(e))?.hide(),o=(e=null)=>{a&&a!==e&&bootstrap.Popover.getInstance(a)?.hide()},s=()=>e.forEach(e=>r(e));e.forEach(e=>{const i=n(e),l=i.dataset.helpMicro||"Help article not found.",c=e.dataset.helpTitle||"Help unavailable",d=e.dataset.helpSummary||"Help content has not yet been written for this feature.";bootstrap.Tooltip.getOrCreateInstance(i,{title:l,trigger:"hover focus",placement:"top",container:"body"});const p=bootstrap.Popover.getOrCreateInstance(e,{title:c,trigger:"click",placement:"auto",container:"body",html:!0,customClass:"plotline-help-popover",content(){const t=document.createElement("div"),a=document.createElement("p");a.className="mb-2",a.textContent=d;const n=document.createElement("a");return n.href=e.dataset.helpUrl||"#",n.textContent="More...",n.className="plotline-help-more",n.addEventListener("click",t=>{t.preventDefault(),o(),s(),e.dispatchEvent(new CustomEvent("plotline:help-more",{bubbles:!0,detail:{key:e.dataset.helpKey||""}}))}),t.append(a,n),t}});t.set(e,p),e.addEventListener("click",t=>{window.PlotLineHelpDrawer?.isActive?.()&&(t.preventDefault(),t.stopPropagation(),o(),r(e),window.PlotLineHelpPopovers?.hideAll(),window.PlotLineHelpDrawer.open(e.dataset.helpKey||""))}),e.addEventListener("show.bs.popover",t=>{window.PlotLineHelpDrawer?.isActive?.()?t.preventDefault():(o(e),r(e))}),e.addEventListener("shown.bs.popover",()=>{a=e,r(e)}),e.addEventListener("hidden.bs.popover",()=>{a===e&&(a=null)})}),document.addEventListener("click",e=>{const t=e.target instanceof Element?e.target:null;if(!t||!a)return;if(t.closest("[data-help-icon]"))return;const n=document.querySelector(`#${a.getAttribute("aria-describedby")}`);n?.contains(t)||o()}),document.addEventListener("keydown",e=>{"Escape"===e.key&&o()}),window.PlotLineHelpPopovers={hideAll(){t.forEach(e=>e.hide()),s(),a=null}}})(),(()=>{const e=document.querySelector("[data-help-layout]"),t=document.querySelector("[data-help-drawer]"),a=document.querySelector("[data-help-content]"),n=document.querySelector("[data-help-splitter]"),r=document.querySelector("[data-help-close]"),o=document.querySelector("[data-help-collapse]"),s=document.querySelector("[data-help-expand]"),i=document.querySelector("[data-help-pin]"),l=document.querySelector("[data-help-drawer-heading]");if(!e||!t||!a)return;const c="plotline.helpDrawer.width",d="plotline.helpDrawer.pinned",p="plotline.helpDrawer.key",u="plotline.helpDrawer.collapsed",m=e=>{try{return"true"===localStorage.getItem(e)}catch{return!1}},h=(e,t)=>{try{localStorage.setItem(e,t)}catch{}},g=t=>{const a=`${((e,t,a)=>Math.min(a,Math.max(t,e)))(Number.parseFloat(t)||25,20,50)}%`;e.style.setProperty("--help-drawer-width",a),h(c,a)},f=e=>{h(d,String(e)),i?.setAttribute("aria-pressed",String(e)),i&&(i.textContent=e?"Unpin":"Pin")},v=t=>{e.classList.toggle("help-collapsed",t),h(u,String(t)),o&&(o.textContent=t?"Expand":"Collapse")},y=async(t,n={})=>{const r=t||"";e.classList.add("help-open"),n.keepCollapsed||v(!1),h(p,r),l&&(l.textContent=r||"Help"),a.innerHTML='

Loading help...

';try{const e=await fetch(`/HelpDrawer/Article?key=${encodeURIComponent(r)}`,{headers:{"X-Requested-With":"XMLHttpRequest"}});a.innerHTML=e.ok?await e.text():'

Help for this feature has not yet been written.

';const t=a.querySelector(".help-drawer-article h2")?.textContent?.trim();l&&t&&(l.textContent=t)}catch{a.innerHTML='

Help for this feature has not yet been written.

'}};window.PlotLineHelpDrawer={isActive:()=>e.classList.contains("help-open"),open:e=>y(e)},g(localStorage.getItem(c)||"25%"),f(m(d)),v(m(u)),document.addEventListener("plotline:help-more",e=>{const t=e.detail?.key||e.target?.dataset?.helpKey||"";window.PlotLineHelpPopovers?.hideAll(),y(t)}),document.addEventListener("click",e=>{const t=e.target instanceof Element?e.target.closest("[data-help-open]"):null;t&&(e.preventDefault(),window.PlotLineHelpPopovers?.hideAll(),y(t.dataset.helpOpen||""))}),r?.addEventListener("click",()=>{e.classList.remove("help-open","help-collapsed"),f(!1)}),o?.addEventListener("click",()=>v(!e.classList.contains("help-collapsed"))),s?.addEventListener("click",()=>v(!1)),s?.addEventListener("keydown",e=>{"Enter"!==e.key&&" "!==e.key||(e.preventDefault(),v(!1))}),i?.addEventListener("click",()=>f(!m(d))),n?.addEventListener("pointerdown",t=>{if(!e.classList.contains("help-open")||e.classList.contains("help-collapsed"))return;t.preventDefault(),document.body.classList.add("help-resizing"),n.setPointerCapture?.(t.pointerId);const a=t=>{const a=e.getBoundingClientRect(),n=(a.right-t.clientX)/a.width*100;g(n)},r=()=>{document.body.classList.remove("help-resizing"),document.removeEventListener("pointermove",a),document.removeEventListener("pointerup",r)};document.addEventListener("pointermove",a),document.addEventListener("pointerup",r)});const w=(()=>{try{return localStorage.getItem(p)||""}catch{return""}})();m(d)&&w&&y(w,{keepCollapsed:!0})})(),(()=>{const e=document.querySelectorAll(".scene-inspector-root");if(!e.length)return;e.forEach(e=>{const t=`plotline.inspector.${e.dataset.sceneId||e.querySelector(".scene-inspector-form [name='SceneID']")?.value||"new"}.`,a=new Set(["overview","timing","characters"]),n=[...e.querySelectorAll(".inspector-section")],r=e.querySelector(".scene-inspector-form"),o=e.querySelector("[data-scene-time-editor]");if(r&&o&&"true"!==o.dataset.enhanced){o.dataset.enhanced="true";const e=r.querySelector("[name='TimeModeID']"),t=o.dataset.exactDatetimeModeId||"",a=o.dataset.exactDateModeId||"",n=[...o.querySelectorAll("[data-time-part-field]")],s={StartDateTime:o.querySelector("[data-date-part-for='StartDateTime']"),EndDateTime:o.querySelector("[data-date-part-for='EndDateTime']")},i={StartDateTime:o.querySelector("[data-time-part-for='StartDateTime']"),EndDateTime:o.querySelector("[data-time-part-for='EndDateTime']")},l={StartDateTime:r.querySelector("input[type='hidden'][name='StartDateTime']"),EndDateTime:r.querySelector("input[type='hidden'][name='EndDateTime']")},c=()=>e?.value===t,d=()=>e?.value===a,p=()=>{const e=c();n.forEach(t=>{t.hidden=!e,t.classList.toggle("d-none",!e)})},u=e=>{const t=l[e],a=s[e]?.value||"",n=i[e]?.value||"";if(!t)return;if(!a)return void(t.value="");if(c())return void(t.value=`${a}T${n||"00:00"}`);if(d())return void(t.value=a);const r=t.value.match(/^\\d{4}-\\d{2}-\\d{2}T(\\d{2}:\\d{2})/)?.[1];t.value=r?`${a}T${r}`:a},m=()=>{u("StartDateTime"),u("EndDateTime")};e?.addEventListener("change",p),r.addEventListener("submit",m),p()}n.forEach(e=>{if("true"===e.dataset.enhanced)return;const n=e.querySelector("h3, h2"),r=e.dataset.sectionTitle||n?.textContent?.trim()||"Overview",o=r.toLowerCase().replace(/&/g,"and").replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"");const s=e.dataset.sectionId||`inspector-${o}`,i=s.replace(/^inspector-/,"");e.id=s,e.dataset.searchText=`${r} ${e.textContent}`.toLowerCase(),e.dataset.enhanced="true";const l=document.createElement("div");for(l.className="inspector-accordion-body";e.firstChild;)l.appendChild(e.firstChild);const c=document.createElement("button");c.type="button",c.className="inspector-accordion-toggle",c.setAttribute("aria-expanded","false"),e.append(c,l);const d=l.querySelectorAll(".asset-event-item, .thread-event-item, .warning-mini-card, .dependency-card, .metric-slider").length;c.innerHTML=`${r}${d||""}`;const p=localStorage.getItem(`${t}${i}`),u=null===p?a.has(i):"open"===p;e.classList.toggle("is-open",u),c.setAttribute("aria-expanded",String(u)),c.addEventListener("click",()=>{const a=!e.classList.contains("is-open");e.classList.toggle("is-open",a),c.setAttribute("aria-expanded",String(a)),localStorage.setItem(`${t}${i}`,a?"open":"closed")})}),e.querySelectorAll(".inspector-nav-links a").forEach(t=>{t.addEventListener("click",a=>{const n=e.querySelector(t.getAttribute("href"));n&&(a.preventDefault(),n.classList.add("is-open"),n.querySelector(".inspector-accordion-toggle")?.setAttribute("aria-expanded","true"),n.scrollIntoView({behavior:"smooth",block:"start"}))})});const s=e.querySelector("[data-inspector-search]");if(s?.addEventListener("input",()=>{const e=s.value.trim().toLowerCase();n.forEach(t=>{const a=!e||t.dataset.searchText.includes(e);t.classList.toggle("is-filtered-out",!a),a&&e&&(t.classList.add("is-open"),t.querySelector(".inspector-accordion-toggle")?.setAttribute("aria-expanded","true"))})}),"IntersectionObserver"in window){const t=[...e.querySelectorAll(".inspector-nav-links a")],a=new IntersectionObserver(e=>{e.forEach(e=>{e.isIntersecting&&t.forEach(t=>{t.classList.toggle("active",t.getAttribute("href")===`#${e.target.id}`)})})},{root:e.closest(".scene-inspector-panel")||null,rootMargin:"-10% 0px -70% 0px"});n.forEach(e=>a.observe(e))}})})(),(()=>{const e=document.querySelectorAll("[data-metric-shape-chart]");if(!e.length)return;const t=["#2f6f63","#b35f3b","#6750a4","#c58b2b","#7d3f52","#33759b","#9c4d8f","#a33d3d","#6f8f3d","#d08a2f","#444b57"],a=new Set(["Overall Intensity","Tension","Emotional Weight","Action"]),n=[],r=()=>{window.requestAnimationFrame(()=>{n.forEach(e=>e.resize())})};window.PlotLineMetricCharts={resizeAll:r},window.addEventListener("plotline:timeline-layout-changed",r);const o={id:"plotlineChapterGuides",afterDraw(e){const t=e.config.options.plugins.plotlineScenes||[],{ctx:a,chartArea:n,scales:r}=e;if(!t.length||!r.x)return;a.save(),a.strokeStyle="rgba(47, 111, 99, 0.16)",a.fillStyle="rgba(82, 75, 65, 0.58)",a.lineWidth=1,a.font="700 10px system-ui, -apple-system, Segoe UI, sans-serif";const o=[];t.forEach((e,a)=>{a&&e.chapterLabel===t[a-1].chapterLabel||o.push({scene:e,index:a})});const s=o.filter(e=>!e.scene.isPlaceholder),i=s.length>40?5:s.length>24?4:s.length>14?2:1;s.forEach((e,t)=>{const{scene:o,index:l}=e,c=r.x.getPixelForValue(l+.5);a.beginPath(),a.moveTo(c,n.top),a.lineTo(c,n.bottom),a.stroke();const d=Number.parseInt(String(o.chapterLabel).replace(/[^0-9]/g,""),10);(0===t||t===s.length-1||1===i||Number.isFinite(d)&&d%i===0)&&a.fillText(o.chapterLabel,Math.min(c+4,n.right-70),n.bottom+22)}),a.restore()}};window.Chart&&Chart.register(o),e.forEach(e=>{const r=e.querySelector("script[type='application/json']"),o=e.querySelector("canvas"),s=e.querySelector("[data-metric-toggles]"),i=e.querySelector("[data-chart-fallback]"),l=e.querySelector("[data-timeline-metric-edit-toolbar]"),c=e.querySelector("[data-edit-metric-status]"),d=e.hasAttribute("data-timeline-metric-editor")&&l&&c;if(!r||!o)return;let p;try{p=JSON.parse(r.textContent||"{}")}catch{return void i?.classList.remove("d-none")}if(!window.Chart||!p.scenes?.length||!p.metrics?.length)return void i?.classList.remove("d-none");const u=new Set(p.defaultMetrics?.length?p.defaultMetrics:a),m=p.scenes.length,h=m>80?10:m>40?5:m>24?4:m>14?2:1,g=p.metrics.map((e,a)=>{const n=new Map(e.points.map(e=>[e.sceneId,e.value])),r=t[a%t.length];return{label:e.metricName,metricTypeId:e.metricTypeId,minValue:Number.isFinite(e.minValue)?e.minValue:1,maxValue:Number.isFinite(e.maxValue)?e.maxValue:10,data:p.scenes.map((e,t)=>{const a=n.get(e.sceneId);return null==a?{x:t+.5,y:null,sceneId:e.sceneId}:{x:t+.5,y:a,sceneId:e.sceneId}}),borderColor:r,backgroundColor:r,pointBackgroundColor:r,pointBorderColor:"#fff",pointBorderWidth:1.5,pointRadius:3,pointHoverRadius:5,borderWidth:2,tension:.35,spanGaps:!0,hidden:!u.has(e.metricName)}});let f=null,v=!1;const y=e=>{c&&(c.textContent=e)},w=()=>g.map((e,t)=>t).filter(e=>b?.isDatasetVisible(e)),S=()=>{const e=w();return 1===e.length?e[0]:-1},L=()=>{if(!d)return;const e=S();g.forEach((t,a)=>{t.pointRadius=a===e?5:3,t.pointHoverRadius=a===e?7:5,t.borderWidth=a===e?3:2});const t=w(),a=e>=0;o.classList.toggle("metric-curve-editing",a),c.classList.toggle("d-none",0===t.length),0===t.length?y(""):y(a?"Drag points up or down to edit this metric.":"Show only one metric line to edit its curve."),b?.update()};s.innerHTML="",g.forEach((e,t)=>{const a=`metric-toggle-${Math.random().toString(36).slice(2)}-${t}`,n=document.createElement("label");n.className="metric-toggle-pill",n.style.setProperty("--metric-colour",e.borderColor),n.innerHTML=`${e.label}`,s.appendChild(n),n.querySelector("input").addEventListener("change",e=>{b.setDatasetVisibility(t,e.target.checked),L(),b.update()})});const b=new Chart(o,{type:"line",data:{datasets:g},options:{responsive:!0,maintainAspectRatio:!1,interaction:{mode:"nearest",intersect:!1},scales:{y:{min:1,max:10,ticks:{stepSize:1},grid:{color:"rgba(82, 75, 65, 0.10)"}},x:{type:"linear",min:0,max:m,bounds:"ticks",ticks:{maxRotation:0,autoSkip:!1,maxTicksLimit:16,callback(e){const t=Math.floor(Number(e));if(t<0||t>=m)return"";const a=p.scenes[t];return 0!==t&&t!==m-1&&t%h!==0||a?.isPlaceholder?"":a?.axisLabel||""}},afterBuildTicks(e){e.ticks=p.scenes.map((e,t)=>({value:t+.5}))},grid:{display:!1}}},plugins:{legend:{display:!1},plotlineScenes:p.scenes,tooltip:{callbacks:{title(e){const t=Math.floor(e[0].parsed.x),a=p.scenes[t];return a.isPlaceholder?a.sceneTitle||"No scene":`${a.chapterLabel}, Scene ${a.sceneNumber}: ${a.sceneTitle}`},label:e=>`${e.dataset.label}: ${e.formattedValue}`,afterBody(e){const t=Math.floor(e[0].parsed.x),a=p.scenes[t],n=[];return a.characterPresence?n.push(a.characterPresence):void 0!==a.characterAppears&&n.push(a.characterAppears?"Character appears":"Character does not appear"),a.bookTitle&&n.push(a.bookTitle),n}}}}}});d&&(L(),o.addEventListener("pointerdown",e=>{f=(e=>{if(!d)return null;const t=S();if(t<0)return null;const a=b.getElementsAtEventForMode(e,"nearest",{intersect:!0},!0).find(e=>e.datasetIndex===t);if(!a)return null;const n=b.data.datasets[a.datasetIndex],r=n?.data?.[a.index];return r?.sceneId&&null!=r.y?{datasetIndex:a.datasetIndex,pointIndex:a.index,previousValue:r.y}:null})(e),f&&(e.preventDefault(),o.setPointerCapture?.(e.pointerId),v=!0)}),o.addEventListener("pointermove",e=>{if(!f)return;const t=b.data.datasets[f.datasetIndex],a=t?.data?.[f.pointIndex];t&&a&&(a.y=((e,t)=>{const a=b.scales.y.getValueForPixel(e.offsetY),n=Math.round(a);return Math.max(t.minValue,Math.min(t.maxValue,n))})(e,t),b.update("none"))}),o.addEventListener("pointerup",async t=>{if(!f)return;const a=f;f=null,o.releasePointerCapture?.(t.pointerId),await(async t=>{const a=b.data.datasets[t.datasetIndex],n=a?.data?.[t.pointIndex];if(!a||!n?.sceneId)return;const r=l?.querySelector("input[name='__RequestVerificationToken']")?.value||"";y("Saving...");try{const t=await fetch(e.dataset.updateUrl||"/SceneMetrics/UpdateSceneMetricValue",{method:"POST",headers:{"Content-Type":"application/json",RequestVerificationToken:r},body:JSON.stringify({sceneId:Number(n.sceneId),metricId:Number(a.metricTypeId),value:Number(n.y)})}),o=await t.json().catch(()=>({}));if(!t.ok||!o.success)throw new Error(o.message||"Save failed");n.y=o.value,y("Saved"),b.update()}catch{n.y=t.previousValue,y("Save failed"),b.update()}})(a),window.setTimeout(()=>{v=!1},0)}),o.addEventListener("pointercancel",e=>{if(!f)return;const t=b.data.datasets[f.datasetIndex],a=t?.data?.[f.pointIndex];a&&(a.y=f.previousValue),f=null,o.releasePointerCapture?.(e.pointerId),v=!1,b.update()})),o.addEventListener("click",e=>{if(v)return void e.preventDefault();const t=b.getElementsAtEventForMode(e,"nearest",{intersect:!0},!0);if(!t.length)return;const a=b.data.datasets[t[0].datasetIndex]?.data?.[t[0].index],n=a?Math.floor(a.x):t[0].index,r=p.scenes[n];r?.timelineUrl&&(window.PlotLineTimelineScroll?.save(),window.location.href=r.timelineUrl)}),n.push(b);const E=window.ResizeObserver?new ResizeObserver(()=>b.resize()):null;E&&(E.observe(e),E.observe(e.querySelector(".metric-chart-frame")||e))})})(),(()=>{const e=document.querySelector("[data-timeline-root]"),t=document.querySelector("[data-timeline-controls]");if(!e||!t)return;const a="plotline.timeline.visibility",n={"scene-cards":!0,"plot-lines":!0,assets:!0,characters:!0,locations:!0,warnings:!0,metrics:!0},r=t=>{Object.entries(t).forEach(([t,a])=>{e.classList.toggle(`hide-${t}`,!a),document.querySelectorAll(`[data-timeline-section='${t}']`).forEach(e=>{e.classList.toggle("timeline-section-hidden",!a)})}),document.querySelectorAll("[data-location-marker]").forEach(e=>{e.classList.toggle("timeline-section-hidden",!t.locations)}),document.querySelectorAll("[data-warning-marker]").forEach(e=>{e.classList.toggle("timeline-section-hidden",!t.warnings)}),document.querySelector("[data-visibility-json]")?.setAttribute("value",JSON.stringify(t))},o=(()=>{try{return{...n,...JSON.parse(localStorage.getItem(a)||"{}")}}catch{return{...n}}})();t.querySelectorAll("[data-timeline-toggle]").forEach(e=>{const t=e.dataset.timelineToggle;e.checked=o[t]??!0,e.addEventListener("change",()=>{o[t]=e.checked,localStorage.setItem(a,JSON.stringify(o)),r(o)})}),t.querySelector("[data-timeline-preset-form]")?.addEventListener("submit",()=>{document.querySelector("[data-visibility-json]")?.setAttribute("value",JSON.stringify(o))}),r(o)})(),(()=>{const e=document.querySelector("[data-timeline-root]");if(!e)return;const t=e.querySelector(".timeline-workspace")||e,a=document.querySelector("[data-timeline-density]"),n=document.querySelector("[data-timeline-zoom]"),r=document.querySelector("[data-timeline-search]"),o=e.querySelector("[data-timeline-minimap]"),s=document.querySelectorAll("[data-timeline-jump], [data-timeline-warning-jump], [data-timeline-entity-jump]"),i=[...e.querySelectorAll(".timeline-scene-card[data-scene-id]")],l="plotline.timeline.collapsed",c="plotline.timeline.density",d="plotline.timeline.zoom",p="plotline.timeline.pending-scroll",u="plotdirector.timelineNavigationDiscovered",m="plotline.timeline.inspectorWidth",h=[".timeline-shell",".plot-lane-board",".asset-lane-board",".character-lane-board",".metric-graph-stack","[data-timeline-minimap]"].join(","),g=["compact","comfortable","expanded"],f=["book","chapter","scene-detail","scene-overview"],v=e.querySelector("[data-inspector-drawer]"),y=e.querySelector("[data-inspector-resizer]"),w=e.querySelector("[data-inspector-close]"),S=null!==localStorage.getItem(l),L=(e=>{try{return new Set(JSON.parse(localStorage.getItem(e)||"[]"))}catch{return new Set}})(l),b=()=>[...e.querySelectorAll(h)],E=t=>{if(!v)return;const{minimum:a,maximum:n,defaultWidth:r}=(()=>{const t=e.getBoundingClientRect().width||window.innerWidth,a=Math.min(420,Math.max(320,t-360)),n=Math.max(a,Math.min(.65*t,t-420));return{minimum:a,maximum:n,defaultWidth:Math.max(a,Math.min(n,.4*t))}})(),o=Math.max(a,Math.min(n,Number(t)||r));e.style.setProperty("--timeline-inspector-width",`${Math.round(o)}px`)};v&&(E(localStorage.getItem(m)),window.addEventListener("resize",()=>E(localStorage.getItem(m)))),(()=>{const r=e.querySelector("[data-timeline-navigation-card]");if(!r)return;const o=r.querySelector("[data-timeline-navigation-dismiss]"),s=r.querySelector("[data-timeline-navigation-demo]"),i=()=>e.querySelector(".timeline-shell"),l=e=>Boolean(e&&e.scrollWidth>e.clientWidth+8),c=e=>Math.max(0,e.scrollWidth-e.clientWidth),d=()=>[t,...b()].filter((e,t,a)=>e&&a.indexOf(e)===t);let p=!1,m=!1,h=!1,g=null;const f=new WeakMap,v=e=>f.set(e,e.scrollLeft),y=(e=!1)=>{if(window.clearTimeout(g),!e||window.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches||r.hidden)return r.classList.remove("is-dismissing"),void(r.hidden=!0);r.classList.add("is-dismissing"),g=window.setTimeout(()=>{r.hidden=!0,r.classList.remove("is-dismissing")},1300)},w=e=>{const t=l(e),a=c(e);e.classList.toggle("timeline-horizontal-overflow",t),e.classList.toggle("has-scroll-left",t&&e.scrollLeft>8),e.classList.toggle("has-scroll-right",t&&e.scrollLeft{l(i())&&!(()=>{try{return"true"===localStorage.getItem(u)}catch{return!1}})()&&!p?(window.clearTimeout(g),r.hidden=!1,r.classList.remove("is-dismissing")):r.classList.contains("is-dismissing")||y(!1),d().forEach(w)},L=()=>{p=!0,y(!0);try{localStorage.setItem(u,"true")}catch{}};d().forEach(e=>{v(e),e.addEventListener("wheel",t=>{if(!t.defaultPrevented&&t.shiftKey&&Math.abs(t.deltaY)>Math.abs(t.deltaX)&&l(e)){const a=e.scrollLeft;t.preventDefault(),e.scrollLeft+=t.deltaY,window.requestAnimationFrame(()=>{w(e),!m&&Math.abs(e.scrollLeft-a)>4&&L(),v(e)})}},{passive:!1}),e.addEventListener("scroll",()=>(e=>{if(w(e),!h||m)return void v(e);const t=f.get(e)??e.scrollLeft;Math.abs(e.scrollLeft-t)>4&&l(e)?L():v(e)})(e),{passive:!0})}),o?.addEventListener("click",L),s?.addEventListener("click",()=>{const e=i();if(!l(e))return void S();const t=e.scrollLeft,a=c(e)-t;let n=Math.min(220,a),r=1;n<24&&t>0&&(n=Math.min(220,t),r=-1),n<4||(m=!0,e.scrollTo({left:t+n*r,behavior:"smooth"}),window.setTimeout(()=>{e.scrollTo({left:t,behavior:"smooth"})},420),window.setTimeout(()=>{m=!1,d().forEach(e=>{v(e),w(e)}),S()},950))}),window.setTimeout(()=>{h=!0,d().forEach(v)},800),window.requestAnimationFrame(S),window.addEventListener("resize",S),window.addEventListener("plotline:timeline-layout-changed",S),a?.addEventListener("change",()=>window.requestAnimationFrame(S)),n?.addEventListener("change",()=>window.requestAnimationFrame(S))})(),y?.addEventListener("pointerdown",t=>{t.preventDefault(),document.body.classList.add("timeline-inspector-resizing"),y.setPointerCapture(t.pointerId);const a=t=>{const a=e.getBoundingClientRect().right-t.clientX;E(a)},n=()=>{document.body.classList.remove("timeline-inspector-resizing");const e=Math.round(v?.getBoundingClientRect().width||0);e>0&&localStorage.setItem(m,String(e)),window.dispatchEvent(new Event("plotline:timeline-layout-changed")),y.removeEventListener("pointermove",a),y.removeEventListener("pointerup",n),y.removeEventListener("pointercancel",n)};y.addEventListener("pointermove",a),y.addEventListener("pointerup",n),y.addEventListener("pointercancel",n)}),w?.addEventListener("click",e=>{e.preventDefault();const t=new URL(window.location.href),a=t.searchParams.get("FocusType")||t.searchParams.get("focusType");t.searchParams.delete("SelectedSceneID"),t.searchParams.delete("selectedSceneId"),t.searchParams.delete("selectedsceneid"),a&&"scene"!==a.toLowerCase()||(t.searchParams.delete("FocusType"),t.searchParams.delete("focusType"),t.searchParams.delete("FocusID"),t.searchParams.delete("focusId")),x(),window.location.href=t.toString()});const x=()=>{try{sessionStorage.setItem(p,JSON.stringify({path:window.location.pathname,top:window.scrollY,left:window.scrollX,workspaceLeft:t.scrollLeft,workspaceTop:t.scrollTop,containers:b().map((e,t)=>({index:t,left:e.scrollLeft,top:e.scrollTop}))}))}catch{}};window.PlotLineTimelineScroll={save:x};const q=(t,a,n)=>{n.forEach(a=>e.classList.remove(`${t}-${a}`)),e.classList.add(`${t}-${a}`)},I=e=>{const t=g.includes(e)?e:"comfortable";q("density",t,g),a&&(a.value=t),localStorage.setItem(c,t),window.requestAnimationFrame(k)},T=e=>{const t=f.includes(e)?e:"chapter";q("zoom",t,f),n&&(n.value=t),localStorage.setItem(d,t),window.requestAnimationFrame(k)},C=(t,a=!0)=>{const n=(t=>e.querySelector(`[data-scene-id='${CSS.escape(String(t))}']`))(t);n&&(n.classList.add("keyboard-focus"),n.scrollIntoView({behavior:"smooth",block:"center",inline:"center"}),a&&n.focus({preventScroll:!0}),window.setTimeout(()=>n.classList.remove("keyboard-focus"),1800))},k=()=>{e.querySelectorAll("[data-plot-line-svg-board]").forEach(e=>{const t=e.querySelector("[data-plot-line-svg]");if(!t)return;let a=e.querySelector("[data-plot-line-health-svg]");a||(a=document.createElementNS("http://www.w3.org/2000/svg","svg"),a.setAttribute("class","plot-lane-svg-overlay plot-lane-svg-health-overlay"),a.setAttribute("data-plot-line-health-svg",""),a.setAttribute("aria-hidden","true"),t.after(a)),t.replaceChildren(),a.replaceChildren();const n=e.getBoundingClientRect(),r=Math.max(e.scrollWidth,n.width),o=Math.max(e.scrollHeight,n.height);[t,a].forEach(e=>{e.setAttribute("viewBox",`0 0 ${r} ${o}`),e.setAttribute("width",String(r)),e.setAttribute("height",String(o))});const s=(e,t={})=>{const a=document.createElementNS("http://www.w3.org/2000/svg",e);return Object.entries(t).forEach(([e,t])=>a.setAttribute(e,String(t))),a},i=[...new Set([...e.querySelectorAll("[data-plot-line-slot]")].map(e=>{const t=e.getBoundingClientRect();return Math.round(t.left-n.left+t.width/2)}))].sort((e,t)=>e-t),l=Math.max(i.length-1,0),c=new Map;e.querySelectorAll("[data-plot-line-row]").forEach(e=>{e.dataset.plotLineId&&c.set(e.dataset.plotLineId,e)});const d=[...c.values()].map(e=>({row:e,plotLineId:e.dataset.plotLineId,colour:e.dataset.plotColour||"#2f6f63",points:[...e.querySelectorAll("[data-plot-event-node]")].map(e=>((e,t)=>{const a=t.closest("[data-plot-line-slot]");if(!a)return null;const r=a.getBoundingClientRect(),o=t.getBoundingClientRect();return{x:o.left-n.left+o.width/2,y:o.top-n.top+o.height/2,sceneX:r.left-n.left+r.width/2,radius:Math.max(o.width,o.height)/2,sceneIndex:0,type:(t.dataset.plotEventType||"Progress").toLowerCase(),targetPlotLineId:t.dataset.targetPlotLineId||"",targetPlotLineIds:(t.dataset.targetPlotLineIds||"").split(",").map(e=>e.trim()).filter(Boolean)}})(0,e)).filter(Boolean).map(e=>({...e,sceneIndex:Math.max(0,i.findIndex(t=>t===Math.round(e.sceneX)))})).sort((e,t)=>e.x-t.x),incomingStartXs:[]})),p=new Map(d.map(e=>[e.plotLineId,e])),u=(e,a,r,o)=>{if(!a)return void(window.console?.warn&&window.console.warn(`Plot line ${o} connector skipped because target plot line data is missing.`));e.x;const i=(e=>{const t=e.getBoundingClientRect();return t.top-n.top+t.height/2})(a),l=Math.max(28,Math.min(46,.28*Math.abs(i-e.y))),c=Math.max(8,e.radius||12),d=e.x+c,p=d+l,u=d+l/2;t.append(s("path",{class:`plot-line-svg-connector plot-line-svg-connector-${o}`,d:`M ${d} ${e.y} C ${u} ${e.y}, ${u} ${i}, ${p} ${i}`,stroke:r}))};d.forEach(e=>{e.points.forEach(e=>{"branch"===e.type&&e.targetPlotLineId&&p.get(e.targetPlotLineId)?.incomingStartXs.push(e.x),"split"===e.type&&e.targetPlotLineIds.forEach(t=>{p.get(t)?.incomingStartXs.push(e.x)})})}),d.forEach(e=>{e.health=(e=>{const t=e.some(e=>"resolve"===e.type),a=e.some(e=>"abandon"===e.type),n=e.find(e=>"resolve"===e.type),r=e.find(e=>"abandon"===e.type),o=e.some(e=>"merge"===e.type&&e.targetPlotLineId),s=e.some(e=>"split"===e.type&&e.targetPlotLineIds.length>=2),i=Boolean(n)&&e.some(e=>"branch"===e.type&&e.targetPlotLineId&&e.sceneIndex>=n.sceneIndex),c=e.reduce((e,t)=>Math.max(e,t.sceneIndex),0),d=!t&&!a&&l-c>=10,p=t&&!o&&!s&&!i;let u="active";return a?u="abandoned":t?u=p?"questionable":"resolved":d&&(u="neglected"),{state:u,isNeglected:d,isDangling:!t&&!a&&!o&&!s&&l>=c,isQuestionable:p,isAbandoned:a,resolvePoint:n,abandonPoint:r}})(e.points),e.state=e.health.state}),d.forEach(e=>{const{colour:a,points:n,incomingStartXs:r,state:o}=e;if(n.length>0){const i=n.find(e=>"start"===e.type),l=r.length?Math.min(...r):null,c=n.find(e=>"split"===e.type||"merge"===e.type),d=n[0],p=n[n.length-1],u=((null===l||i&&i.xe.x-t.x),h=c?m.indexOf(c):-1,g=h>=0?m.slice(0,h+1):m;null!==l&&l{const r=g[n+1];if(!r||r.x<=e.x)return;const i=Math.abs(r.sceneIndex-e.sceneIndex)>=f;t.append(s("path",{class:`plot-line-svg-path plot-line-svg-segment ${i?"plot-line-svg-segment-dormant":""} plotline-state-${o}`,d:`M ${e.x} ${e.y} L ${r.x} ${r.y}`,stroke:a}))})}}),d.forEach(({points:e,colour:t})=>{e.forEach(e=>{"branch"!==e.type&&"merge"!==e.type||u(e,c.get(e.targetPlotLineId),t,e.type),"split"===e.type&&e.targetPlotLineIds.length>=2?e.targetPlotLineIds.forEach(a=>{u(e,c.get(a),t,e.type)}):"split"===e.type&&e.targetPlotLineIds.length>0&&window.console?.warn&&window.console.warn("Plot line split connector skipped because fewer than two targets are available.")})}),d.forEach(e=>{const t=e.lineEndPoint||e.points[e.points.length-1],n=[];e.health?.isNeglected&&t&&n.push({point:t,kind:"neglected",label:"Dormant Thread",reason:"No activity for 10+ scenes.",action:"Add a Progress, Reveal or Resolve event."}),e.health?.isDangling&&t&&n.push({point:t,kind:"dangling",label:"Unresolved Thread",reason:"Thread contains no Resolve or Abandon event by the end of the current timeline.",action:"Review ending scenes and add Resolve or Abandon where appropriate."}),e.health?.isQuestionable&&e.health.resolvePoint&&n.push({point:e.health.resolvePoint,kind:"questionable",label:"Missing Closure",reason:"Resolved without merge, split, or branch.",action:"Verify this thread has sufficient payoff."}),e.health?.isAbandoned&&e.health.abandonPoint&&n.push({point:e.health.abandonPoint,kind:"abandoned",label:"Abandoned Thread",reason:"This plot line was abandoned.",action:"Check this is intentional."});const r=new Map;n.forEach(e=>{const t=`${Math.round(e.point.x)}:${Math.round(e.point.y)}`;r.has(t)||r.set(t,{point:e.point,warnings:[]}),r.get(t).warnings.push(e)}),r.forEach(({point:e,warnings:t})=>((e,t)=>{const n=Math.max(18,(e.radius||12)+8),r=t[0]?.kind||"warning",o=s("g",{class:`plotline-health-marker plotline-health-marker-${r}`}),i=s("title");i.textContent=(e=>e.map(e=>[`Warning: ${e.label}`,`Reason: ${e.reason}`,`Suggested Action: ${e.action}`].join("\n")).join("\n\n"))(t),o.append(i);const l=e.x+n,c=e.y-13;if("questionable"===r){o.append(s("circle",{cx:l,cy:c,r:9}));const e=s("text",{x:l,y:c+4,"text-anchor":"middle"});e.textContent=t.length>1?String(t.length):"?",o.append(e)}else if(o.append(s("circle",{cx:l,cy:c,r:10})),o.append(s("path",{d:`M ${l} ${c-6} L ${l+6} ${c+5} L ${l-6} ${c+5} Z`})),o.append(s("line",{x1:l,y1:c-2,x2:l,y2:c+2.5})),o.append(s("circle",{cx:l,cy:c+5.3,r:1.2})),t.length>1){const e=s("text",{x:l+11,y:c-6,"text-anchor":"middle",class:"plotline-health-count"});e.textContent=String(t.length),o.append(e)}a.append(o)})(e,t))})})},A=(e,t)=>{document.querySelectorAll(`[data-collapse-body='${CSS.escape(e)}']`).forEach(e=>{e.classList.toggle("timeline-section-collapsed",t)}),document.querySelectorAll(`[data-collapse-toggle='${CSS.escape(e)}']`).forEach(e=>{e.classList.toggle("is-collapsed",t),e.setAttribute("aria-expanded",String(!t))})};document.querySelectorAll("[data-collapse-toggle]").forEach(e=>{const t=e.dataset.collapseToggle;S||"collapsed"!==e.dataset.collapseDefault||L.add(t);const a=L.has(t);A(t,a),e.addEventListener("click",()=>{const e=!L.has(t);e?L.add(t):L.delete(t),A(t,e),localStorage.setItem(l,JSON.stringify([...L])),k(),window.dispatchEvent(new Event("plotline:timeline-layout-changed"))})}),a?.addEventListener("change",()=>I(a.value)),n?.addEventListener("change",()=>T(n.value)),I(localStorage.getItem(c)||"comfortable"),T(localStorage.getItem(d)||"chapter");const $=(()=>{try{return null!==sessionStorage.getItem(p)}catch{return!1}})();window.requestAnimationFrame(()=>{k(),((e="auto")=>{const t=o?.querySelector("[data-active-chapter='true']");if(!o||!t)return;const a=o.getBoundingClientRect(),n=t.getBoundingClientRect(),r=n.left+n.width/2,s=a.left+a.width/2;(n.lefta.right)&&o.scrollBy({left:r-s,behavior:e})})("auto"),$&&(()=>{let e=null;try{e=JSON.parse(sessionStorage.getItem(p)||"null"),sessionStorage.removeItem(p)}catch{try{sessionStorage.removeItem(p)}catch{}return}e&&e.path===window.location.pathname&&window.requestAnimationFrame(()=>{t.scrollLeft=Number(e.workspaceLeft)||0,t.scrollTop=Number(e.workspaceTop)||0;const a=b();(e.containers||[]).forEach(e=>{const t=a[e.index];t&&(t.scrollLeft=Number(e.left)||0,t.scrollTop=Number(e.top)||0)}),window.scrollTo(Number(e.left)||0,Number(e.top)||0)})})()}),window.addEventListener("resize",k),window.addEventListener("plotline:timeline-layout-changed",k);e.addEventListener("click",t=>{if(0!==t.button||t.metaKey||t.ctrlKey||t.shiftKey||t.altKey)return;const a=t.target instanceof Element?t.target:null,n=a?.closest("a[href]");if(!n||!e.contains(n))return;[...new URL(n.href,window.location.href).searchParams.keys()].some(e=>"selectedsceneid"===e.toLowerCase())&&x()},{capture:!0});const D=()=>{const e=r?.value.trim().toLowerCase()||"";let t=null;return i.forEach(a=>{const n=!e||(a.dataset.timelineSearchText||"").toLowerCase().includes(e);a.classList.toggle("search-hit",Boolean(e&&n)),a.classList.toggle("search-dim",Boolean(e&&!n)),!t&&e&&n&&(t=a)}),t};r?.addEventListener("input",D),r?.addEventListener("keydown",e=>{if("Enter"!==e.key)return;const t=D();t&&(e.preventDefault(),C(t.dataset.sceneId))}),s.forEach(e=>{e.addEventListener("change",()=>{e.value&&C(e.value)})}),document.querySelectorAll("[data-jump-scene]").forEach(e=>{e.addEventListener("click",()=>{e.dataset.jumpScene&&C(e.dataset.jumpScene)})}),document.addEventListener("keydown",e=>{const a=document.activeElement?.tagName?.toLowerCase(),o=["input","select","textarea"].includes(a)||document.activeElement?.isContentEditable;if((e.ctrlKey||e.metaKey)&&"f"===e.key.toLowerCase()&&r)return e.preventDefault(),r.focus(),void r.select();if("Escape"===e.key){const e=new URL(window.location.href),t=e.searchParams.has("FocusType")||e.searchParams.has("FocusID");return e.searchParams.delete("FocusType"),e.searchParams.delete("FocusID"),void(t?window.location.href=e.toString():r?.value&&(r.value="",D()))}if(!o){if("ArrowLeft"===e.key||"ArrowRight"===e.key)return e.preventDefault(),void t.scrollBy({left:"ArrowLeft"===e.key?-260:260,behavior:"smooth"});if("+"===e.key||"="===e.key||"-"===e.key){const t=f.indexOf(n?.value||"chapter"),a="-"===e.key?-1:1,r=Math.min(f.length-1,Math.max(0,t+a));T(f[r])}}})})(),(()=>{const e=document.querySelector("[data-timeline-root]"),t=document.querySelector("[data-drag-drop-panel]");if(!t)return;const a=new Map([...document.querySelectorAll("[data-drag-form]")].map(e=>[e.dataset.dragForm,e])),n=t.querySelector("[data-drag-panel-title]"),r=t.querySelector("[data-drag-panel-kicker]"),o=t.querySelector("[data-drag-panel-summary]"),s=document.querySelector("[data-scene-move-modal]"),i=s&&window.bootstrap?.Modal?window.bootstrap.Modal.getOrCreateInstance(s):null,l=s?.querySelector("[data-scene-move-title]"),c=s?.querySelector("[data-scene-move-summary]"),d=s?.querySelector("[data-scene-move-submit]"),p="plotline.timeline.scroll";let u=null,m=0;const h=(e,t,a)=>{const n=e?.querySelector(`[name='${CSS.escape(t)}']`);n&&(n.value=a??"")},g=e=>e?.selectedOptions?.[0]?.textContent?.trim()||"",f=e=>`“${e||"this scene"}”`,v=(e,t,a,n,r)=>t&&a&&t===a?`Move ${f(e.label)} to this new position within ${a}?`:t&&a?`Move ${f(e.label)} from ${t} to ${a}?`:`Move ${f(e.label)} ${n.toLowerCase()} ${r}?`,y=(e,s,p,u)=>{if("scene"===e)return t.classList.add("d-none"),t.querySelectorAll("[data-drag-form]").forEach(e=>e.classList.add("d-none")),a.get("scene")?.classList.remove("d-none"),l&&(l.textContent=s),c&&(c.textContent=p),d&&d.classList.toggle("d-none",s.toLowerCase().startsWith("cannot")||s.toLowerCase().startsWith("scene already")),void(i?i.show():t.classList.remove("d-none"));a.forEach((t,a)=>t.classList.toggle("d-none",a!==e)),t.classList.remove("d-none"),n.textContent=s,r.textContent=u,o.textContent=p,t.scrollIntoView({behavior:"smooth",block:"center"})},w=()=>{t.classList.add("d-none"),a.forEach(e=>e.classList.add("d-none"))},S=()=>{document.querySelectorAll(".drop-target-active, .drop-before, .drop-after, .chapter-drop-active, .drop-chapter-end").forEach(e=>e.classList.remove("drop-target-active","drop-before","drop-after","chapter-drop-active","drop-chapter-end"))};try{const t=JSON.parse(sessionStorage.getItem(p)||"null");t&&(sessionStorage.removeItem(p),requestAnimationFrame(()=>{const a=e?.querySelector(".timeline-shell");a&&(a.scrollLeft=t.left||0),window.scrollTo({top:t.top||0})}))}catch{sessionStorage.removeItem(p)}const L=e=>{try{const t=JSON.parse(e.dataTransfer.getData("application/json")||"{}");return t.type?t:u||{}}catch{return u||{}}};document.querySelectorAll("[data-drag-type][draggable='true']").forEach(e=>{e.addEventListener("dragstart",t=>((e,t)=>{const a={type:t.dataset.dragType,id:t.dataset.dragId,label:t.dataset.dragLabel||t.textContent.trim()};e.dataTransfer.effectAllowed="copyMove",e.dataTransfer.setData("application/json",JSON.stringify(a)),e.dataTransfer.setData("text/plain",`${a.type}:${a.id}`),u=a,document.body.classList.add("drag-active",`dragging-${a.type}`),t.classList.add("is-dragging")})(t,e)),e.addEventListener("dragend",()=>{e.classList.remove("is-dragging"),document.body.classList.remove("drag-active","dragging-scene","dragging-character","dragging-asset","dragging-location"),u=null,S()})}),t.querySelectorAll("[data-drag-cancel]").forEach(e=>e.addEventListener("click",w)),a.get("scene")?.addEventListener("submit",()=>{const t=e?.querySelector(".timeline-shell");try{sessionStorage.setItem(p,JSON.stringify({left:t?.scrollLeft||0,top:window.scrollY||0}))}catch{}}),e?.querySelectorAll(".timeline-scene-card[data-scene-id]").forEach(t=>{t.addEventListener("click",e=>{Date.now(){const a=L(e);["scene","character","asset"].includes(a.type)&&(e.preventDefault(),e.stopPropagation(),e.dataTransfer.dropEffect="scene"===a.type?"move":"copy",t.classList.add("drop-target-active"),t.classList.toggle("drop-before","scene"===a.type&&e.offsetX=t.clientWidth/2))}),t.addEventListener("dragleave",()=>t.classList.remove("drop-target-active","drop-before","drop-after")),t.addEventListener("drop",n=>{const r=L(n);if(!["scene","character","asset"].includes(r.type))return;n.preventDefault(),n.stopPropagation(),m=Date.now()+800,t.classList.remove("drop-target-active","drop-before","drop-after");const o=t.dataset.sceneId;if("scene"===r.type){if(r.id===o)return void y("scene","Cannot move scene","Drop a scene before or after a different scene.","Scene move");const s=a.get("scene"),i=n.offsetX{const n=t.closest("[data-chapter-drop-target]"),r=t.dataset.chapterId||n?.dataset.chapterId,o=t.dataset.chapterLabel||n?.dataset.chapterLabel||"this chapter";t.addEventListener("dragover",e=>{"scene"===L(e).type&&r&&(e.target.closest(".timeline-scene-card[data-scene-id]")||(e.preventDefault(),e.dataTransfer.dropEffect="move",t.classList.add("drop-target-active","drop-chapter-end"),n?.classList.add("chapter-drop-active")))}),t.addEventListener("dragleave",e=>{t.contains(e.relatedTarget)||(t.classList.remove("drop-target-active","drop-chapter-end"),n?.classList.remove("chapter-drop-active"))}),t.addEventListener("drop",n=>{const s=L(n);if("scene"!==s.type||!r)return;if(n.target.closest(".timeline-scene-card[data-scene-id]"))return;n.preventDefault(),n.stopPropagation(),m=Date.now()+800,S();const i=e.querySelector(`.timeline-scene-card[data-scene-id='${CSS.escape(s.id)}']`);if(i?.dataset.chapterId===r&&t.lastElementChild?.dataset?.sceneId===s.id)return void y("scene","Scene already here",`${s.label} is already at the end of ${o}.`,"Scene move");const l=a.get("scene");h(l,"SceneID",s.id),h(l,"AnchorSceneID",""),h(l,"TargetChapterID",r),h(l,"Position","End"),y("scene","Move Scene?",v(s,i?.dataset.chapterLabel||"",o,"After",o),"Scene move")})});const b=a.get("asset-dependency"),E=()=>{const e=b?.dataset.sourceLabel||"Source asset",a=b?.dataset.targetLabel||"Target asset",n=g(b?.querySelector("[name='AssetDependencyTypeID']"))||"Requires",r=g(b?.querySelector("[name='SourceRequiredStateID']"))||"the required state",o=g(b?.querySelector("[name='TargetBlockedStateID']"))||"the blocked state",s=t.querySelector("[data-asset-dependency-preview]");s&&(s.textContent=`${e} ${n.toLowerCase()} ${a}. ${e} should be ${r} before ${a} can be ${o}.`)};b?.querySelectorAll("select").forEach(e=>e.addEventListener("change",E)),document.querySelectorAll("[data-asset-drop-target], .drag-chip.asset").forEach(e=>{e.addEventListener("dragover",t=>{"asset"===L(t).type&&(t.preventDefault(),t.dataTransfer.dropEffect="copy",e.classList.add("drop-target-active"))}),e.addEventListener("dragleave",()=>e.classList.remove("drop-target-active")),e.addEventListener("drop",t=>{const a=L(t),n=e.dataset.assetId||e.dataset.dragId,r=e.dataset.assetLabel||e.dataset.dragLabel||e.textContent.trim();"asset"===a.type&&n&&(t.preventDefault(),e.classList.remove("drop-target-active"),a.id!==n?(h(b,"SourceAssetID",a.id),h(b,"TargetAssetID",n),b.dataset.sourceLabel=a.label,b.dataset.targetLabel=r,E(),y("asset-dependency","Create asset dependency",`${a.label} -> ${r}`,"Asset dependency")):y("asset-dependency","Cannot create dependency","Drop one asset onto a different asset.","Asset dependency"))})}),document.querySelectorAll("[data-drag-type='location']").forEach(e=>{e.addEventListener("dragover",t=>{"location"===L(t).type&&(t.preventDefault(),t.dataTransfer.dropEffect="copy",e.classList.add("drop-target-active"))}),e.addEventListener("dragleave",()=>e.classList.remove("drop-target-active")),e.addEventListener("drop",t=>{const n=L(t),r=e.dataset.dragId,o=e.dataset.dragLabel||e.textContent.trim();if("location"!==n.type)return;if(t.preventDefault(),e.classList.remove("drop-target-active"),n.id===r)return void y("location-relationship","Cannot create relationship","Drop one location onto a different location.","Location relationship");const s=a.get("location-relationship");h(s,"FromLocationID",n.id),h(s,"ToLocationID",r),y("location-relationship","Create location relationship",`${n.label} -> ${o}`,"Location drop")})})})(); \ No newline at end of file +(()=>{const e="plotline.theme",t=document.querySelectorAll("[data-theme-choice]"),n=n=>{const a="dark"===n?"dark":"light";document.documentElement.dataset.theme=a,document.documentElement.dataset.bsTheme=a,(t=>{try{localStorage.setItem(e,t)}catch{}})(a),t.forEach(e=>{const t=e.dataset.themeChoice===a;e.classList.toggle("active",t),e.setAttribute("aria-pressed",String(t))})};t.forEach(e=>{e.addEventListener("click",()=>n(e.dataset.themeChoice))}),n((()=>{try{return localStorage.getItem(e)}catch{return null}})()||"light")})(),(()=>{const e=document.querySelector("[data-trial-banner]");if(!e)return;const t=`plotline.trialBanner.dismissed.${e.dataset.trialBannerKey||"current"}`;try{if("true"===localStorage.getItem(t))return void(e.hidden=!0)}catch{}e.querySelector("[data-trial-banner-dismiss]")?.addEventListener("click",()=>{e.hidden=!0;try{localStorage.setItem(t,"true")}catch{}})})(),(()=>{const e=document.querySelector("[data-word-companion-follow-toggle]");if(!e||!window.signalR)return;const t="plotdirector.followWordCompanion",n=["/pricing","/about","/contact","/privacy","/terms","/admin","/billing","/account","/login","/register","/feature-requests/admin","/featurerequests/admin","/manageaccount"];let a=null,r=null;const o=()=>{try{return"true"===localStorage.getItem(t)}catch{return!1}},s=t=>{e.setAttribute("aria-pressed",String(t)),e.classList.toggle("active",t),e.title=t?"PlotDirector will follow the current Word Companion scene.":"Enable this to let PlotDirector follow the current Word Companion scene."},i=(e,t)=>{if("string"!=typeof e||!e.startsWith(t))return"";try{const t=new URL(e,window.location.origin);return t.origin===window.location.origin?`${t.pathname}${t.search}${t.hash}`:""}catch{return""}},l=e=>{if(!o()||!(()=>{const e=window.location.pathname.toLowerCase();return"/"!==e&&""!==e&&!n.some(t=>e===t||e.startsWith(`${t}/`))})()||!e)return;`${window.location.pathname}${window.location.search}${window.location.hash}`!==e&&window.location.assign(e)};s(o()),e.addEventListener("click",()=>{const e=!o();(e=>{try{localStorage.setItem(t,e?"true":"false")}catch{}})(e),s(e)});const c=(new signalR.HubConnectionBuilder).withUrl("/hubs/word-companion-follow").withAutomaticReconnect().build();c.on("wordCompanionSceneChanged",e=>{const t=Number.parseInt(e?.sceneId||e?.SceneId||"",10);if(!Number.isInteger(t)||t<=0||t===a)return;a=t;const n=i(e?.sceneUrl||e?.SceneUrl||"","/Scenes/Details/");l(n)}),c.on("wordCompanionCharactersCreated",e=>{const t=Number.parseInt(e?.projectId||e?.ProjectId||"",10);if(!Number.isInteger(t)||t<=0||t===r)return;r=t;const n=i(e?.charactersUrl||e?.CharactersUrl||"","/Characters");l(n)}),c.start().catch(e=>{console.debug("Word Companion follow connection unavailable.",e)})})(),(()=>{const e=document.querySelectorAll(".scene-inspector-root");if(!e.length)return;e.forEach(e=>{e.addEventListener("submit",e=>{const t=e.target;if(!(t instanceof HTMLFormElement))return;let n=t.querySelector("input[name='ReturnUrl']");n||(n=document.createElement("input"),n.type="hidden",n.name="ReturnUrl",t.appendChild(n)),n.value=`${window.location.pathname}${window.location.search}${window.location.hash}`},!0)})})(),(()=>{const e=document.querySelectorAll(".scene-inspector-root");if(!e.length)return;const t=(e,t,n)=>{const a=e.querySelector("[data-scene-occupancy-status]");a&&(a.textContent=t,a.dataset.saveState=n||"")},n=(e,t)=>{const n=document.createElement("div");n.innerHTML=t;const a=n.querySelector("[data-scene-occupancy-form]");if(a){e.replaceWith(a);const t=a.closest(".scene-inspector-root")?.querySelector(".scene-inspector-form"),n=t?.querySelector("[name='FloorPlanID']"),r=t?.querySelector("[name='InitialFloorPlanFloorID']"),o=a.querySelector("[name='FloorPlanID']"),s=a.querySelector("[name='InitialFloorPlanFloorID']");n&&o&&(n.value=o.value),r&&s&&(r.value=s.value)}};e.forEach(e=>{e.addEventListener("change",async e=>{const a=e.target.closest?.("[data-occupancy-plan-select]");if(!a)return;const r=a.closest("[data-scene-occupancy-form]"),o=r?.querySelector("[name='SceneID']")?.value,s=r?.dataset.editorUrl;if(!r||!o||!s)return;t(r,"Loading...","saving");const i=new URL(s,window.location.origin);i.searchParams.set("sceneId",o),a.value&&i.searchParams.set("floorPlanId",a.value);try{const e=await fetch(i,{headers:{"X-Requested-With":"XMLHttpRequest"}});if(!e.ok)throw new Error("The occupancy editor could not be refreshed.");n(r,await e.text())}catch(e){t(r,e.message||"Load failed","failed")}}),e.addEventListener("submit",async e=>{const a=e.target.closest?.("[data-scene-occupancy-form]");if(a){e.preventDefault(),t(a,"Saving...","saving");try{const e=await fetch(a.action,{method:"POST",body:new FormData(a),headers:{"X-Requested-With":"XMLHttpRequest"}});if(!e.ok){let t="Save failed";if((e.headers.get("content-type")||"").includes("application/json")){t=(await e.json()).message||t}throw new Error(t)}n(a,await e.text())}catch(e){t(a,e.message||"Save failed","failed")}}})})})(),(()=>{const e=document.getElementById("plotlineConfirmModal"),t=e&&window.bootstrap?new bootstrap.Modal(e):null,n=e?.querySelector("#plotlineConfirmModalTitle"),a=e?.querySelector("#plotlineConfirmModalMessage"),r=e?.querySelector("[data-confirm-submit]"),o=e?.querySelector("[data-delete-confirm-field]"),s=e?.querySelector("[data-delete-confirm-input]");let i=null,l=null;e?.addEventListener("hidden.bs.modal",()=>{i=null,l=null,s&&(s.value=""),o?.classList.add("d-none"),r?.removeAttribute("disabled")}),s?.addEventListener("input",()=>{"true"===i?.dataset.requireDeleteText&&r&&(r.disabled="DELETE"!==s.value.trim())}),r?.addEventListener("click",()=>{if(i){if("true"===i.dataset.requireDeleteText){const e=i.querySelector("[data-delete-confirm-target], [name='confirmationText']");e&&(e.value=s?.value.trim()||"")}i.dataset.confirmed="true",t?.hide(),i.requestSubmit&&l?i.requestSubmit(l):i.requestSubmit?i.requestSubmit():i.submit()}}),document.addEventListener("submit",c=>{const d=c.target;if(!(d instanceof HTMLFormElement)||"true"===d.dataset.confirmed||"true"===d.dataset.confirmSkip||"true"===d.dataset.noDeleteConfirm)return;const u=d.dataset.confirmMessage,p=c.submitter instanceof HTMLElement?c.submitter:d.querySelector("button[type='submit']"),m=p?.textContent||"",h=d.getAttribute("action")||"",g=/restore/i.test(m)||/\/restore\b/i.test(h),f=/delete forever/i.test(m)||/\/deleteforever\b/i.test(h),v=!g&&!f&&(/archive/i.test(m)||/\/archive\b/i.test(h)),y=!f&&/(delete|remove)/i.test(m);if(!(u||v||g||y||f))return;const w=u||(v?"Archive this item?\n\nThis will hide it from active lists and timelines, but the data will be kept and can be restored later.":g?"Restore this item?\n\nThis will return it to active lists and timelines where applicable.":f?"Permanently delete this item?\n\nThis cannot be undone. Any linked planning data may also be removed or become unavailable. Only continue if you are certain.":"Remove this item?\n\nThis removes the link or supporting record. Major story items are archived instead of permanently deleted.");if(!(t&&e&&n&&a&&r))return;c.preventDefault();const S=(e=>{const t=e.split(/\n\s*\n/);return{title:t.shift()?.trim()||"Confirm action",body:t.join("\n\n").trim()}})(w);i=d,l=p,n.textContent=d.dataset.confirmTitle||S.title,a.textContent=d.dataset.confirmBody||S.body,r.textContent=d.dataset.confirmButtonText||m.trim()||"Confirm",r.className=`btn ${d.dataset.confirmButtonClass||(g?"btn-primary":"btn-danger")}`;const L="true"===d.dataset.requireDeleteText||f;o?.classList.toggle("d-none",!L),L&&r&&(r.disabled=!0,s?.focus()),t.show(),L&&window.setTimeout(()=>s?.focus(),200)})})(),(()=>{const e=document.querySelectorAll("[data-help-icon]");if(!e.length||!window.bootstrap)return;const t=new Map;let n=null;const a=e=>e.querySelector("[data-help-tooltip]")||e,r=e=>bootstrap.Tooltip.getInstance(a(e))?.hide(),o=(e=null)=>{n&&n!==e&&bootstrap.Popover.getInstance(n)?.hide()},s=()=>e.forEach(e=>r(e));e.forEach(e=>{const i=a(e),l=i.dataset.helpMicro||"Help article not found.",c=e.dataset.helpTitle||"Help unavailable",d=e.dataset.helpSummary||"Help content has not yet been written for this feature.";bootstrap.Tooltip.getOrCreateInstance(i,{title:l,trigger:"hover focus",placement:"top",container:"body"});const u=bootstrap.Popover.getOrCreateInstance(e,{title:c,trigger:"click",placement:"auto",container:"body",html:!0,customClass:"plotline-help-popover",content(){const t=document.createElement("div"),n=document.createElement("p");n.className="mb-2",n.textContent=d;const a=document.createElement("a");return a.href=e.dataset.helpUrl||"#",a.textContent="More...",a.className="plotline-help-more",a.addEventListener("click",t=>{t.preventDefault(),o(),s(),e.dispatchEvent(new CustomEvent("plotline:help-more",{bubbles:!0,detail:{key:e.dataset.helpKey||""}}))}),t.append(n,a),t}});t.set(e,u),e.addEventListener("click",t=>{window.PlotLineHelpDrawer?.isActive?.()&&(t.preventDefault(),t.stopPropagation(),o(),r(e),window.PlotLineHelpPopovers?.hideAll(),window.PlotLineHelpDrawer.open(e.dataset.helpKey||""))}),e.addEventListener("show.bs.popover",t=>{window.PlotLineHelpDrawer?.isActive?.()?t.preventDefault():(o(e),r(e))}),e.addEventListener("shown.bs.popover",()=>{n=e,r(e)}),e.addEventListener("hidden.bs.popover",()=>{n===e&&(n=null)})}),document.addEventListener("click",e=>{const t=e.target instanceof Element?e.target:null;if(!t||!n)return;if(t.closest("[data-help-icon]"))return;const a=document.querySelector(`#${n.getAttribute("aria-describedby")}`);a?.contains(t)||o()}),document.addEventListener("keydown",e=>{"Escape"===e.key&&o()}),window.PlotLineHelpPopovers={hideAll(){t.forEach(e=>e.hide()),s(),n=null}}})(),(()=>{const e=document.querySelector("[data-help-layout]"),t=document.querySelector("[data-help-drawer]"),n=document.querySelector("[data-help-content]"),a=document.querySelector("[data-help-splitter]"),r=document.querySelector("[data-help-close]"),o=document.querySelector("[data-help-collapse]"),s=document.querySelector("[data-help-expand]"),i=document.querySelector("[data-help-pin]"),l=document.querySelector("[data-help-drawer-heading]");if(!e||!t||!n)return;const c="plotline.helpDrawer.width",d="plotline.helpDrawer.pinned",u="plotline.helpDrawer.key",p="plotline.helpDrawer.collapsed",m=e=>{try{return"true"===localStorage.getItem(e)}catch{return!1}},h=(e,t)=>{try{localStorage.setItem(e,t)}catch{}},g=t=>{const n=`${((e,t,n)=>Math.min(n,Math.max(t,e)))(Number.parseFloat(t)||25,20,50)}%`;e.style.setProperty("--help-drawer-width",n),h(c,n)},f=e=>{h(d,String(e)),i?.setAttribute("aria-pressed",String(e)),i&&(i.textContent=e?"Unpin":"Pin")},v=t=>{e.classList.toggle("help-collapsed",t),h(p,String(t)),o&&(o.textContent=t?"Expand":"Collapse")},y=async(t,a={})=>{const r=t||"";e.classList.add("help-open"),a.keepCollapsed||v(!1),h(u,r),l&&(l.textContent=r||"Help"),n.innerHTML='

Loading help...

';try{const e=await fetch(`/HelpDrawer/Article?key=${encodeURIComponent(r)}`,{headers:{"X-Requested-With":"XMLHttpRequest"}});n.innerHTML=e.ok?await e.text():'

Help for this feature has not yet been written.

';const t=n.querySelector(".help-drawer-article h2")?.textContent?.trim();l&&t&&(l.textContent=t)}catch{n.innerHTML='

Help for this feature has not yet been written.

'}};window.PlotLineHelpDrawer={isActive:()=>e.classList.contains("help-open"),open:e=>y(e)},g(localStorage.getItem(c)||"25%"),f(m(d)),v(m(p)),document.addEventListener("plotline:help-more",e=>{const t=e.detail?.key||e.target?.dataset?.helpKey||"";window.PlotLineHelpPopovers?.hideAll(),y(t)}),document.addEventListener("click",e=>{const t=e.target instanceof Element?e.target.closest("[data-help-open]"):null;t&&(e.preventDefault(),window.PlotLineHelpPopovers?.hideAll(),y(t.dataset.helpOpen||""))}),r?.addEventListener("click",()=>{e.classList.remove("help-open","help-collapsed"),f(!1)}),o?.addEventListener("click",()=>v(!e.classList.contains("help-collapsed"))),s?.addEventListener("click",()=>v(!1)),s?.addEventListener("keydown",e=>{"Enter"!==e.key&&" "!==e.key||(e.preventDefault(),v(!1))}),i?.addEventListener("click",()=>f(!m(d))),a?.addEventListener("pointerdown",t=>{if(!e.classList.contains("help-open")||e.classList.contains("help-collapsed"))return;t.preventDefault(),document.body.classList.add("help-resizing"),a.setPointerCapture?.(t.pointerId);const n=t=>{const n=e.getBoundingClientRect(),a=(n.right-t.clientX)/n.width*100;g(a)},r=()=>{document.body.classList.remove("help-resizing"),document.removeEventListener("pointermove",n),document.removeEventListener("pointerup",r)};document.addEventListener("pointermove",n),document.addEventListener("pointerup",r)});const w=(()=>{try{return localStorage.getItem(u)||""}catch{return""}})();m(d)&&w&&y(w,{keepCollapsed:!0})})(),(()=>{const e=document.querySelectorAll(".scene-inspector-root");if(!e.length)return;e.forEach(e=>{const t=`plotline.inspector.${e.dataset.sceneId||e.querySelector(".scene-inspector-form [name='SceneID']")?.value||"new"}.`,n=new Set(["overview","timing","characters"]),a=[...e.querySelectorAll(".inspector-section")],r=e.querySelector(".scene-inspector-form"),o=e.querySelector("[data-scene-time-editor]");if(r&&o&&"true"!==o.dataset.enhanced){o.dataset.enhanced="true";const e=r.querySelector("[name='TimeModeID']"),t=o.dataset.exactDatetimeModeId||"",n=o.dataset.exactDateModeId||"",a=[...o.querySelectorAll("[data-time-part-field]")],s={StartDateTime:o.querySelector("[data-date-part-for='StartDateTime']"),EndDateTime:o.querySelector("[data-date-part-for='EndDateTime']")},i={StartDateTime:o.querySelector("[data-time-part-for='StartDateTime']"),EndDateTime:o.querySelector("[data-time-part-for='EndDateTime']")},l={StartDateTime:r.querySelector("input[type='hidden'][name='StartDateTime']"),EndDateTime:r.querySelector("input[type='hidden'][name='EndDateTime']")},c=()=>e?.value===t,d=()=>e?.value===n,u=()=>{const e=c();a.forEach(t=>{t.hidden=!e,t.classList.toggle("d-none",!e)})},p=e=>{const t=l[e],n=s[e]?.value||"",a=i[e]?.value||"";if(!t)return;if(!n)return void(t.value="");if(c())return void(t.value=`${n}T${a||"00:00"}`);if(d())return void(t.value=n);const r=t.value.match(/^\\d{4}-\\d{2}-\\d{2}T(\\d{2}:\\d{2})/)?.[1];t.value=r?`${n}T${r}`:n},m=()=>{p("StartDateTime"),p("EndDateTime")};e?.addEventListener("change",u),r.addEventListener("submit",m),u()}a.forEach(e=>{if("true"===e.dataset.enhanced)return;const a=e.querySelector("h3, h2"),r=e.dataset.sectionTitle||a?.textContent?.trim()||"Overview",o=r.toLowerCase().replace(/&/g,"and").replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"");const s=e.dataset.sectionId||`inspector-${o}`,i=s.replace(/^inspector-/,"");e.id=s,e.dataset.searchText=`${r} ${e.textContent}`.toLowerCase(),e.dataset.enhanced="true";const l=document.createElement("div");for(l.className="inspector-accordion-body";e.firstChild;)l.appendChild(e.firstChild);const c=document.createElement("button");c.type="button",c.className="inspector-accordion-toggle",c.setAttribute("aria-expanded","false"),e.append(c,l);const d=l.querySelectorAll(".asset-event-item, .thread-event-item, .warning-mini-card, .dependency-card, .metric-slider").length;c.innerHTML=`${r}${d||""}`;const u=localStorage.getItem(`${t}${i}`),p=null===u?n.has(i):"open"===u;e.classList.toggle("is-open",p),c.setAttribute("aria-expanded",String(p)),c.addEventListener("click",()=>{const n=!e.classList.contains("is-open");e.classList.toggle("is-open",n),c.setAttribute("aria-expanded",String(n)),localStorage.setItem(`${t}${i}`,n?"open":"closed")})}),e.querySelectorAll(".inspector-nav-links a").forEach(t=>{t.addEventListener("click",n=>{const a=e.querySelector(t.getAttribute("href"));a&&(n.preventDefault(),a.classList.add("is-open"),a.querySelector(".inspector-accordion-toggle")?.setAttribute("aria-expanded","true"),a.scrollIntoView({behavior:"smooth",block:"start"}))})});const s=e.querySelector("[data-inspector-search]");if(s?.addEventListener("input",()=>{const e=s.value.trim().toLowerCase();a.forEach(t=>{const n=!e||t.dataset.searchText.includes(e);t.classList.toggle("is-filtered-out",!n),n&&e&&(t.classList.add("is-open"),t.querySelector(".inspector-accordion-toggle")?.setAttribute("aria-expanded","true"))})}),"IntersectionObserver"in window){const t=[...e.querySelectorAll(".inspector-nav-links a")],n=new IntersectionObserver(e=>{e.forEach(e=>{e.isIntersecting&&t.forEach(t=>{t.classList.toggle("active",t.getAttribute("href")===`#${e.target.id}`)})})},{root:e.closest(".scene-inspector-panel")||null,rootMargin:"-10% 0px -70% 0px"});a.forEach(e=>n.observe(e))}})})(),(()=>{const e=document.querySelectorAll("[data-metric-shape-chart]");if(!e.length)return;const t=["#2f6f63","#b35f3b","#6750a4","#c58b2b","#7d3f52","#33759b","#9c4d8f","#a33d3d","#6f8f3d","#d08a2f","#444b57"],n=new Set(["Overall Intensity","Tension","Emotional Weight","Action"]),a=[],r=()=>{window.requestAnimationFrame(()=>{a.forEach(e=>e.resize())})};window.PlotLineMetricCharts={resizeAll:r},window.addEventListener("plotline:timeline-layout-changed",r);const o={id:"plotlineChapterGuides",afterDraw(e){const t=e.config.options.plugins.plotlineScenes||[],{ctx:n,chartArea:a,scales:r}=e;if(!t.length||!r.x)return;n.save(),n.strokeStyle="rgba(47, 111, 99, 0.16)",n.fillStyle="rgba(82, 75, 65, 0.58)",n.lineWidth=1,n.font="700 10px system-ui, -apple-system, Segoe UI, sans-serif";const o=[];t.forEach((e,n)=>{n&&e.chapterLabel===t[n-1].chapterLabel||o.push({scene:e,index:n})});const s=o.filter(e=>!e.scene.isPlaceholder),i=s.length>40?5:s.length>24?4:s.length>14?2:1;s.forEach((e,t)=>{const{scene:o,index:l}=e,c=r.x.getPixelForValue(l+.5);n.beginPath(),n.moveTo(c,a.top),n.lineTo(c,a.bottom),n.stroke();const d=Number.parseInt(String(o.chapterLabel).replace(/[^0-9]/g,""),10);(0===t||t===s.length-1||1===i||Number.isFinite(d)&&d%i===0)&&n.fillText(o.chapterLabel,Math.min(c+4,a.right-70),a.bottom+22)}),n.restore()}};window.Chart&&Chart.register(o),e.forEach(e=>{const r=e.querySelector("script[type='application/json']"),o=e.querySelector("canvas"),s=e.querySelector("[data-metric-toggles]"),i=e.querySelector("[data-chart-fallback]"),l=e.querySelector("[data-timeline-metric-edit-toolbar]"),c=e.querySelector("[data-edit-metric-status]"),d=e.hasAttribute("data-timeline-metric-editor")&&l&&c;if(!r||!o)return;let u;try{u=JSON.parse(r.textContent||"{}")}catch{return void i?.classList.remove("d-none")}if(!window.Chart||!u.scenes?.length||!u.metrics?.length)return void i?.classList.remove("d-none");const p=new Set(u.defaultMetrics?.length?u.defaultMetrics:n),m=u.scenes.length,h=m>80?10:m>40?5:m>24?4:m>14?2:1,g=u.metrics.map((e,n)=>{const a=new Map(e.points.map(e=>[e.sceneId,e.value])),r=t[n%t.length];return{label:e.metricName,metricTypeId:e.metricTypeId,minValue:Number.isFinite(e.minValue)?e.minValue:1,maxValue:Number.isFinite(e.maxValue)?e.maxValue:10,data:u.scenes.map((e,t)=>{const n=a.get(e.sceneId);return null==n?{x:t+.5,y:null,sceneId:e.sceneId}:{x:t+.5,y:n,sceneId:e.sceneId}}),borderColor:r,backgroundColor:r,pointBackgroundColor:r,pointBorderColor:"#fff",pointBorderWidth:1.5,pointRadius:3,pointHoverRadius:5,borderWidth:2,tension:.35,spanGaps:!0,hidden:!p.has(e.metricName)}});let f=null,v=!1;const y=e=>{c&&(c.textContent=e)},w=()=>g.map((e,t)=>t).filter(e=>b?.isDatasetVisible(e)),S=()=>{const e=w();return 1===e.length?e[0]:-1},L=()=>{if(!d)return;const e=S();g.forEach((t,n)=>{t.pointRadius=n===e?5:3,t.pointHoverRadius=n===e?7:5,t.borderWidth=n===e?3:2});const t=w(),n=e>=0;o.classList.toggle("metric-curve-editing",n),c.classList.toggle("d-none",0===t.length),0===t.length?y(""):y(n?"Drag points up or down to edit this metric.":"Show only one metric line to edit its curve."),b?.update()};s.innerHTML="",g.forEach((e,t)=>{const n=`metric-toggle-${Math.random().toString(36).slice(2)}-${t}`,a=document.createElement("label");a.className="metric-toggle-pill",a.style.setProperty("--metric-colour",e.borderColor),a.innerHTML=`${e.label}`,s.appendChild(a),a.querySelector("input").addEventListener("change",e=>{b.setDatasetVisibility(t,e.target.checked),L(),b.update()})});const b=new Chart(o,{type:"line",data:{datasets:g},options:{responsive:!0,maintainAspectRatio:!1,interaction:{mode:"nearest",intersect:!1},scales:{y:{min:1,max:10,ticks:{stepSize:1},grid:{color:"rgba(82, 75, 65, 0.10)"}},x:{type:"linear",min:0,max:m,bounds:"ticks",ticks:{maxRotation:0,autoSkip:!1,maxTicksLimit:16,callback(e){const t=Math.floor(Number(e));if(t<0||t>=m)return"";const n=u.scenes[t];return 0!==t&&t!==m-1&&t%h!==0||n?.isPlaceholder?"":n?.axisLabel||""}},afterBuildTicks(e){e.ticks=u.scenes.map((e,t)=>({value:t+.5}))},grid:{display:!1}}},plugins:{legend:{display:!1},plotlineScenes:u.scenes,tooltip:{callbacks:{title(e){const t=Math.floor(e[0].parsed.x),n=u.scenes[t];return n.isPlaceholder?n.sceneTitle||"No scene":`${n.chapterLabel}, Scene ${n.sceneNumber}: ${n.sceneTitle}`},label:e=>`${e.dataset.label}: ${e.formattedValue}`,afterBody(e){const t=Math.floor(e[0].parsed.x),n=u.scenes[t],a=[];return n.characterPresence?a.push(n.characterPresence):void 0!==n.characterAppears&&a.push(n.characterAppears?"Character appears":"Character does not appear"),n.bookTitle&&a.push(n.bookTitle),a}}}}}});d&&(L(),o.addEventListener("pointerdown",e=>{f=(e=>{if(!d)return null;const t=S();if(t<0)return null;const n=b.getElementsAtEventForMode(e,"nearest",{intersect:!0},!0).find(e=>e.datasetIndex===t);if(!n)return null;const a=b.data.datasets[n.datasetIndex],r=a?.data?.[n.index];return r?.sceneId&&null!=r.y?{datasetIndex:n.datasetIndex,pointIndex:n.index,previousValue:r.y}:null})(e),f&&(e.preventDefault(),o.setPointerCapture?.(e.pointerId),v=!0)}),o.addEventListener("pointermove",e=>{if(!f)return;const t=b.data.datasets[f.datasetIndex],n=t?.data?.[f.pointIndex];t&&n&&(n.y=((e,t)=>{const n=b.scales.y.getValueForPixel(e.offsetY),a=Math.round(n);return Math.max(t.minValue,Math.min(t.maxValue,a))})(e,t),b.update("none"))}),o.addEventListener("pointerup",async t=>{if(!f)return;const n=f;f=null,o.releasePointerCapture?.(t.pointerId),await(async t=>{const n=b.data.datasets[t.datasetIndex],a=n?.data?.[t.pointIndex];if(!n||!a?.sceneId)return;const r=l?.querySelector("input[name='__RequestVerificationToken']")?.value||"";y("Saving...");try{const t=await fetch(e.dataset.updateUrl||"/SceneMetrics/UpdateSceneMetricValue",{method:"POST",headers:{"Content-Type":"application/json",RequestVerificationToken:r},body:JSON.stringify({sceneId:Number(a.sceneId),metricId:Number(n.metricTypeId),value:Number(a.y)})}),o=await t.json().catch(()=>({}));if(!t.ok||!o.success)throw new Error(o.message||"Save failed");a.y=o.value,y("Saved"),b.update()}catch{a.y=t.previousValue,y("Save failed"),b.update()}})(n),window.setTimeout(()=>{v=!1},0)}),o.addEventListener("pointercancel",e=>{if(!f)return;const t=b.data.datasets[f.datasetIndex],n=t?.data?.[f.pointIndex];n&&(n.y=f.previousValue),f=null,o.releasePointerCapture?.(e.pointerId),v=!1,b.update()})),o.addEventListener("click",e=>{if(v)return void e.preventDefault();const t=b.getElementsAtEventForMode(e,"nearest",{intersect:!0},!0);if(!t.length)return;const n=b.data.datasets[t[0].datasetIndex]?.data?.[t[0].index],a=n?Math.floor(n.x):t[0].index,r=u.scenes[a];r?.timelineUrl&&(window.PlotLineTimelineScroll?.save(),window.location.href=r.timelineUrl)}),a.push(b);const E=window.ResizeObserver?new ResizeObserver(()=>b.resize()):null;E&&(E.observe(e),E.observe(e.querySelector(".metric-chart-frame")||e))})})(),(()=>{const e=document.querySelector("[data-timeline-root]"),t=document.querySelector("[data-timeline-controls]");if(!e||!t)return;const n="plotline.timeline.visibility",a={"scene-cards":!0,"plot-lines":!0,assets:!0,characters:!0,locations:!0,warnings:!0,metrics:!0},r=t=>{Object.entries(t).forEach(([t,n])=>{e.classList.toggle(`hide-${t}`,!n),document.querySelectorAll(`[data-timeline-section='${t}']`).forEach(e=>{e.classList.toggle("timeline-section-hidden",!n)})}),document.querySelectorAll("[data-location-marker]").forEach(e=>{e.classList.toggle("timeline-section-hidden",!t.locations)}),document.querySelectorAll("[data-warning-marker]").forEach(e=>{e.classList.toggle("timeline-section-hidden",!t.warnings)}),document.querySelector("[data-visibility-json]")?.setAttribute("value",JSON.stringify(t))},o=(()=>{try{return{...a,...JSON.parse(localStorage.getItem(n)||"{}")}}catch{return{...a}}})();t.querySelectorAll("[data-timeline-toggle]").forEach(e=>{const t=e.dataset.timelineToggle;e.checked=o[t]??!0,e.addEventListener("change",()=>{o[t]=e.checked,localStorage.setItem(n,JSON.stringify(o)),r(o)})}),t.querySelector("[data-timeline-preset-form]")?.addEventListener("submit",()=>{document.querySelector("[data-visibility-json]")?.setAttribute("value",JSON.stringify(o))}),r(o)})(),(()=>{const e=document.querySelector("[data-timeline-root]");if(!e)return;const t=e.querySelector(".timeline-workspace")||e,n=document.querySelector("[data-timeline-density]"),a=document.querySelector("[data-timeline-zoom]"),r=document.querySelector("[data-timeline-search]"),o=e.querySelector("[data-timeline-minimap]"),s=document.querySelectorAll("[data-timeline-jump], [data-timeline-warning-jump], [data-timeline-entity-jump]"),i=[...e.querySelectorAll(".timeline-scene-card[data-scene-id]")],l="plotline.timeline.collapsed",c="plotline.timeline.density",d="plotline.timeline.zoom",u="plotline.timeline.pending-scroll",p="plotdirector.timelineNavigationDiscovered",m="plotline.timeline.inspectorWidth",h=[".timeline-shell",".plot-lane-board",".asset-lane-board",".character-lane-board",".metric-graph-stack","[data-timeline-minimap]"].join(","),g=["compact","comfortable","expanded"],f=["book","chapter","scene-detail","scene-overview"],v=e.querySelector("[data-inspector-drawer]"),y=e.querySelector("[data-inspector-resizer]"),w=e.querySelector("[data-inspector-close]"),S=null!==localStorage.getItem(l),L=(e=>{try{return new Set(JSON.parse(localStorage.getItem(e)||"[]"))}catch{return new Set}})(l),b=()=>[...e.querySelectorAll(h)],E=t=>{if(!v)return;const{minimum:n,maximum:a,defaultWidth:r}=(()=>{const t=e.getBoundingClientRect().width||window.innerWidth,n=Math.min(420,Math.max(320,t-360)),a=Math.max(n,Math.min(.65*t,t-420));return{minimum:n,maximum:a,defaultWidth:Math.max(n,Math.min(a,.4*t))}})(),o=Math.max(n,Math.min(a,Number(t)||r));e.style.setProperty("--timeline-inspector-width",`${Math.round(o)}px`)};v&&(E(localStorage.getItem(m)),window.addEventListener("resize",()=>E(localStorage.getItem(m)))),(()=>{const r=e.querySelector("[data-timeline-navigation-card]");if(!r)return;const o=r.querySelector("[data-timeline-navigation-dismiss]"),s=r.querySelector("[data-timeline-navigation-demo]"),i=()=>e.querySelector(".timeline-shell"),l=e=>Boolean(e&&e.scrollWidth>e.clientWidth+8),c=e=>Math.max(0,e.scrollWidth-e.clientWidth),d=()=>[t,...b()].filter((e,t,n)=>e&&n.indexOf(e)===t);let u=!1,m=!1,h=!1,g=null;const f=new WeakMap,v=e=>f.set(e,e.scrollLeft),y=(e=!1)=>{if(window.clearTimeout(g),!e||window.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches||r.hidden)return r.classList.remove("is-dismissing"),void(r.hidden=!0);r.classList.add("is-dismissing"),g=window.setTimeout(()=>{r.hidden=!0,r.classList.remove("is-dismissing")},1300)},w=e=>{const t=l(e),n=c(e);e.classList.toggle("timeline-horizontal-overflow",t),e.classList.toggle("has-scroll-left",t&&e.scrollLeft>8),e.classList.toggle("has-scroll-right",t&&e.scrollLeft{l(i())&&!(()=>{try{return"true"===localStorage.getItem(p)}catch{return!1}})()&&!u?(window.clearTimeout(g),r.hidden=!1,r.classList.remove("is-dismissing")):r.classList.contains("is-dismissing")||y(!1),d().forEach(w)},L=()=>{u=!0,y(!0);try{localStorage.setItem(p,"true")}catch{}};d().forEach(e=>{v(e),e.addEventListener("wheel",t=>{if(!t.defaultPrevented&&t.shiftKey&&Math.abs(t.deltaY)>Math.abs(t.deltaX)&&l(e)){const n=e.scrollLeft;t.preventDefault(),e.scrollLeft+=t.deltaY,window.requestAnimationFrame(()=>{w(e),!m&&Math.abs(e.scrollLeft-n)>4&&L(),v(e)})}},{passive:!1}),e.addEventListener("scroll",()=>(e=>{if(w(e),!h||m)return void v(e);const t=f.get(e)??e.scrollLeft;Math.abs(e.scrollLeft-t)>4&&l(e)?L():v(e)})(e),{passive:!0})}),o?.addEventListener("click",L),s?.addEventListener("click",()=>{const e=i();if(!l(e))return void S();const t=e.scrollLeft,n=c(e)-t;let a=Math.min(220,n),r=1;a<24&&t>0&&(a=Math.min(220,t),r=-1),a<4||(m=!0,e.scrollTo({left:t+a*r,behavior:"smooth"}),window.setTimeout(()=>{e.scrollTo({left:t,behavior:"smooth"})},420),window.setTimeout(()=>{m=!1,d().forEach(e=>{v(e),w(e)}),S()},950))}),window.setTimeout(()=>{h=!0,d().forEach(v)},800),window.requestAnimationFrame(S),window.addEventListener("resize",S),window.addEventListener("plotline:timeline-layout-changed",S),n?.addEventListener("change",()=>window.requestAnimationFrame(S)),a?.addEventListener("change",()=>window.requestAnimationFrame(S))})(),y?.addEventListener("pointerdown",t=>{t.preventDefault(),document.body.classList.add("timeline-inspector-resizing"),y.setPointerCapture(t.pointerId);const n=t=>{const n=e.getBoundingClientRect().right-t.clientX;E(n)},a=()=>{document.body.classList.remove("timeline-inspector-resizing");const e=Math.round(v?.getBoundingClientRect().width||0);e>0&&localStorage.setItem(m,String(e)),window.dispatchEvent(new Event("plotline:timeline-layout-changed")),y.removeEventListener("pointermove",n),y.removeEventListener("pointerup",a),y.removeEventListener("pointercancel",a)};y.addEventListener("pointermove",n),y.addEventListener("pointerup",a),y.addEventListener("pointercancel",a)}),w?.addEventListener("click",e=>{e.preventDefault();const t=new URL(window.location.href),n=t.searchParams.get("FocusType")||t.searchParams.get("focusType");t.searchParams.delete("SelectedSceneID"),t.searchParams.delete("selectedSceneId"),t.searchParams.delete("selectedsceneid"),n&&"scene"!==n.toLowerCase()||(t.searchParams.delete("FocusType"),t.searchParams.delete("focusType"),t.searchParams.delete("FocusID"),t.searchParams.delete("focusId")),I(),window.location.href=t.toString()});const I=()=>{try{sessionStorage.setItem(u,JSON.stringify({path:window.location.pathname,top:window.scrollY,left:window.scrollX,workspaceLeft:t.scrollLeft,workspaceTop:t.scrollTop,containers:b().map((e,t)=>({index:t,left:e.scrollLeft,top:e.scrollTop}))}))}catch{}};window.PlotLineTimelineScroll={save:I};const x=(t,n,a)=>{a.forEach(n=>e.classList.remove(`${t}-${n}`)),e.classList.add(`${t}-${n}`)},q=e=>{const t=g.includes(e)?e:"comfortable";x("density",t,g),n&&(n.value=t),localStorage.setItem(c,t),window.requestAnimationFrame(k)},C=e=>{const t=f.includes(e)?e:"chapter";x("zoom",t,f),a&&(a.value=t),localStorage.setItem(d,t),window.requestAnimationFrame(k)},T=(t,n=!0)=>{const a=(t=>e.querySelector(`[data-scene-id='${CSS.escape(String(t))}']`))(t);a&&(a.classList.add("keyboard-focus"),a.scrollIntoView({behavior:"smooth",block:"center",inline:"center"}),n&&a.focus({preventScroll:!0}),window.setTimeout(()=>a.classList.remove("keyboard-focus"),1800))},k=()=>{e.querySelectorAll("[data-plot-line-svg-board]").forEach(e=>{const t=e.querySelector("[data-plot-line-svg]");if(!t)return;let n=e.querySelector("[data-plot-line-health-svg]");n||(n=document.createElementNS("http://www.w3.org/2000/svg","svg"),n.setAttribute("class","plot-lane-svg-overlay plot-lane-svg-health-overlay"),n.setAttribute("data-plot-line-health-svg",""),n.setAttribute("aria-hidden","true"),t.after(n)),t.replaceChildren(),n.replaceChildren();const a=e.getBoundingClientRect(),r=Math.max(e.scrollWidth,a.width),o=Math.max(e.scrollHeight,a.height);[t,n].forEach(e=>{e.setAttribute("viewBox",`0 0 ${r} ${o}`),e.setAttribute("width",String(r)),e.setAttribute("height",String(o))});const s=(e,t={})=>{const n=document.createElementNS("http://www.w3.org/2000/svg",e);return Object.entries(t).forEach(([e,t])=>n.setAttribute(e,String(t))),n},i=[...new Set([...e.querySelectorAll("[data-plot-line-slot]")].map(e=>{const t=e.getBoundingClientRect();return Math.round(t.left-a.left+t.width/2)}))].sort((e,t)=>e-t),l=Math.max(i.length-1,0),c=new Map;e.querySelectorAll("[data-plot-line-row]").forEach(e=>{e.dataset.plotLineId&&c.set(e.dataset.plotLineId,e)});const d=[...c.values()].map(e=>({row:e,plotLineId:e.dataset.plotLineId,colour:e.dataset.plotColour||"#2f6f63",points:[...e.querySelectorAll("[data-plot-event-node]")].map(e=>((e,t)=>{const n=t.closest("[data-plot-line-slot]");if(!n)return null;const r=n.getBoundingClientRect(),o=t.getBoundingClientRect();return{x:o.left-a.left+o.width/2,y:o.top-a.top+o.height/2,sceneX:r.left-a.left+r.width/2,radius:Math.max(o.width,o.height)/2,sceneIndex:0,type:(t.dataset.plotEventType||"Progress").toLowerCase(),targetPlotLineId:t.dataset.targetPlotLineId||"",targetPlotLineIds:(t.dataset.targetPlotLineIds||"").split(",").map(e=>e.trim()).filter(Boolean)}})(0,e)).filter(Boolean).map(e=>({...e,sceneIndex:Math.max(0,i.findIndex(t=>t===Math.round(e.sceneX)))})).sort((e,t)=>e.x-t.x),incomingStartXs:[]})),u=new Map(d.map(e=>[e.plotLineId,e])),p=(e,n,r,o)=>{if(!n)return void(window.console?.warn&&window.console.warn(`Plot line ${o} connector skipped because target plot line data is missing.`));e.x;const i=(e=>{const t=e.getBoundingClientRect();return t.top-a.top+t.height/2})(n),l=Math.max(28,Math.min(46,.28*Math.abs(i-e.y))),c=Math.max(8,e.radius||12),d=e.x+c,u=d+l,p=d+l/2;t.append(s("path",{class:`plot-line-svg-connector plot-line-svg-connector-${o}`,d:`M ${d} ${e.y} C ${p} ${e.y}, ${p} ${i}, ${u} ${i}`,stroke:r}))};d.forEach(e=>{e.points.forEach(e=>{"branch"===e.type&&e.targetPlotLineId&&u.get(e.targetPlotLineId)?.incomingStartXs.push(e.x),"split"===e.type&&e.targetPlotLineIds.forEach(t=>{u.get(t)?.incomingStartXs.push(e.x)})})}),d.forEach(e=>{e.health=(e=>{const t=e.some(e=>"resolve"===e.type),n=e.some(e=>"abandon"===e.type),a=e.find(e=>"resolve"===e.type),r=e.find(e=>"abandon"===e.type),o=e.some(e=>"merge"===e.type&&e.targetPlotLineId),s=e.some(e=>"split"===e.type&&e.targetPlotLineIds.length>=2),i=Boolean(a)&&e.some(e=>"branch"===e.type&&e.targetPlotLineId&&e.sceneIndex>=a.sceneIndex),c=e.reduce((e,t)=>Math.max(e,t.sceneIndex),0),d=!t&&!n&&l-c>=10,u=t&&!o&&!s&&!i;let p="active";return n?p="abandoned":t?p=u?"questionable":"resolved":d&&(p="neglected"),{state:p,isNeglected:d,isDangling:!t&&!n&&!o&&!s&&l>=c,isQuestionable:u,isAbandoned:n,resolvePoint:a,abandonPoint:r}})(e.points),e.state=e.health.state}),d.forEach(e=>{const{colour:n,points:a,incomingStartXs:r,state:o}=e;if(a.length>0){const i=a.find(e=>"start"===e.type),l=r.length?Math.min(...r):null,c=a.find(e=>"split"===e.type||"merge"===e.type),d=a[0],u=a[a.length-1],p=((null===l||i&&i.xe.x-t.x),h=c?m.indexOf(c):-1,g=h>=0?m.slice(0,h+1):m;null!==l&&l{const r=g[a+1];if(!r||r.x<=e.x)return;const i=Math.abs(r.sceneIndex-e.sceneIndex)>=f;t.append(s("path",{class:`plot-line-svg-path plot-line-svg-segment ${i?"plot-line-svg-segment-dormant":""} plotline-state-${o}`,d:`M ${e.x} ${e.y} L ${r.x} ${r.y}`,stroke:n}))})}}),d.forEach(({points:e,colour:t})=>{e.forEach(e=>{"branch"!==e.type&&"merge"!==e.type||p(e,c.get(e.targetPlotLineId),t,e.type),"split"===e.type&&e.targetPlotLineIds.length>=2?e.targetPlotLineIds.forEach(n=>{p(e,c.get(n),t,e.type)}):"split"===e.type&&e.targetPlotLineIds.length>0&&window.console?.warn&&window.console.warn("Plot line split connector skipped because fewer than two targets are available.")})}),d.forEach(e=>{const t=e.lineEndPoint||e.points[e.points.length-1],a=[];e.health?.isNeglected&&t&&a.push({point:t,kind:"neglected",label:"Dormant Thread",reason:"No activity for 10+ scenes.",action:"Add a Progress, Reveal or Resolve event."}),e.health?.isDangling&&t&&a.push({point:t,kind:"dangling",label:"Unresolved Thread",reason:"Thread contains no Resolve or Abandon event by the end of the current timeline.",action:"Review ending scenes and add Resolve or Abandon where appropriate."}),e.health?.isQuestionable&&e.health.resolvePoint&&a.push({point:e.health.resolvePoint,kind:"questionable",label:"Missing Closure",reason:"Resolved without merge, split, or branch.",action:"Verify this thread has sufficient payoff."}),e.health?.isAbandoned&&e.health.abandonPoint&&a.push({point:e.health.abandonPoint,kind:"abandoned",label:"Abandoned Thread",reason:"This plot line was abandoned.",action:"Check this is intentional."});const r=new Map;a.forEach(e=>{const t=`${Math.round(e.point.x)}:${Math.round(e.point.y)}`;r.has(t)||r.set(t,{point:e.point,warnings:[]}),r.get(t).warnings.push(e)}),r.forEach(({point:e,warnings:t})=>((e,t)=>{const a=Math.max(18,(e.radius||12)+8),r=t[0]?.kind||"warning",o=s("g",{class:`plotline-health-marker plotline-health-marker-${r}`}),i=s("title");i.textContent=(e=>e.map(e=>[`Warning: ${e.label}`,`Reason: ${e.reason}`,`Suggested Action: ${e.action}`].join("\n")).join("\n\n"))(t),o.append(i);const l=e.x+a,c=e.y-13;if("questionable"===r){o.append(s("circle",{cx:l,cy:c,r:9}));const e=s("text",{x:l,y:c+4,"text-anchor":"middle"});e.textContent=t.length>1?String(t.length):"?",o.append(e)}else if(o.append(s("circle",{cx:l,cy:c,r:10})),o.append(s("path",{d:`M ${l} ${c-6} L ${l+6} ${c+5} L ${l-6} ${c+5} Z`})),o.append(s("line",{x1:l,y1:c-2,x2:l,y2:c+2.5})),o.append(s("circle",{cx:l,cy:c+5.3,r:1.2})),t.length>1){const e=s("text",{x:l+11,y:c-6,"text-anchor":"middle",class:"plotline-health-count"});e.textContent=String(t.length),o.append(e)}n.append(o)})(e,t))})})},A=(e,t)=>{document.querySelectorAll(`[data-collapse-body='${CSS.escape(e)}']`).forEach(e=>{e.classList.toggle("timeline-section-collapsed",t)}),document.querySelectorAll(`[data-collapse-toggle='${CSS.escape(e)}']`).forEach(e=>{e.classList.toggle("is-collapsed",t),e.setAttribute("aria-expanded",String(!t))})};document.querySelectorAll("[data-collapse-toggle]").forEach(e=>{const t=e.dataset.collapseToggle;S||"collapsed"!==e.dataset.collapseDefault||L.add(t);const n=L.has(t);A(t,n),e.addEventListener("click",()=>{const e=!L.has(t);e?L.add(t):L.delete(t),A(t,e),localStorage.setItem(l,JSON.stringify([...L])),k(),window.dispatchEvent(new Event("plotline:timeline-layout-changed"))})}),n?.addEventListener("change",()=>q(n.value)),a?.addEventListener("change",()=>C(a.value)),q(localStorage.getItem(c)||"comfortable"),C(localStorage.getItem(d)||"chapter");const $=(()=>{try{return null!==sessionStorage.getItem(u)}catch{return!1}})();window.requestAnimationFrame(()=>{k(),((e="auto")=>{const t=o?.querySelector("[data-active-chapter='true']");if(!o||!t)return;const n=o.getBoundingClientRect(),a=t.getBoundingClientRect(),r=a.left+a.width/2,s=n.left+n.width/2;(a.leftn.right)&&o.scrollBy({left:r-s,behavior:e})})("auto"),$&&(()=>{let e=null;try{e=JSON.parse(sessionStorage.getItem(u)||"null"),sessionStorage.removeItem(u)}catch{try{sessionStorage.removeItem(u)}catch{}return}e&&e.path===window.location.pathname&&window.requestAnimationFrame(()=>{t.scrollLeft=Number(e.workspaceLeft)||0,t.scrollTop=Number(e.workspaceTop)||0;const n=b();(e.containers||[]).forEach(e=>{const t=n[e.index];t&&(t.scrollLeft=Number(e.left)||0,t.scrollTop=Number(e.top)||0)}),window.scrollTo(Number(e.left)||0,Number(e.top)||0)})})()}),window.addEventListener("resize",k),window.addEventListener("plotline:timeline-layout-changed",k);e.addEventListener("click",t=>{if(0!==t.button||t.metaKey||t.ctrlKey||t.shiftKey||t.altKey)return;const n=t.target instanceof Element?t.target:null,a=n?.closest("a[href]");if(!a||!e.contains(a))return;[...new URL(a.href,window.location.href).searchParams.keys()].some(e=>"selectedsceneid"===e.toLowerCase())&&I()},{capture:!0});const D=()=>{const e=r?.value.trim().toLowerCase()||"";let t=null;return i.forEach(n=>{const a=!e||(n.dataset.timelineSearchText||"").toLowerCase().includes(e);n.classList.toggle("search-hit",Boolean(e&&a)),n.classList.toggle("search-dim",Boolean(e&&!a)),!t&&e&&a&&(t=n)}),t};r?.addEventListener("input",D),r?.addEventListener("keydown",e=>{if("Enter"!==e.key)return;const t=D();t&&(e.preventDefault(),T(t.dataset.sceneId))}),s.forEach(e=>{e.addEventListener("change",()=>{e.value&&T(e.value)})}),document.querySelectorAll("[data-jump-scene]").forEach(e=>{e.addEventListener("click",()=>{e.dataset.jumpScene&&T(e.dataset.jumpScene)})}),document.addEventListener("keydown",e=>{const n=document.activeElement?.tagName?.toLowerCase(),o=["input","select","textarea"].includes(n)||document.activeElement?.isContentEditable;if((e.ctrlKey||e.metaKey)&&"f"===e.key.toLowerCase()&&r)return e.preventDefault(),r.focus(),void r.select();if("Escape"===e.key){const e=new URL(window.location.href),t=e.searchParams.has("FocusType")||e.searchParams.has("FocusID");return e.searchParams.delete("FocusType"),e.searchParams.delete("FocusID"),void(t?window.location.href=e.toString():r?.value&&(r.value="",D()))}if(!o){if("ArrowLeft"===e.key||"ArrowRight"===e.key)return e.preventDefault(),void t.scrollBy({left:"ArrowLeft"===e.key?-260:260,behavior:"smooth"});if("+"===e.key||"="===e.key||"-"===e.key){const t=f.indexOf(a?.value||"chapter"),n="-"===e.key?-1:1,r=Math.min(f.length-1,Math.max(0,t+n));C(f[r])}}})})(),(()=>{const e=document.querySelector("[data-timeline-root]"),t=document.querySelector("[data-drag-drop-panel]");if(!t)return;const n=new Map([...document.querySelectorAll("[data-drag-form]")].map(e=>[e.dataset.dragForm,e])),a=t.querySelector("[data-drag-panel-title]"),r=t.querySelector("[data-drag-panel-kicker]"),o=t.querySelector("[data-drag-panel-summary]"),s=document.querySelector("[data-scene-move-modal]"),i=s&&window.bootstrap?.Modal?window.bootstrap.Modal.getOrCreateInstance(s):null,l=s?.querySelector("[data-scene-move-title]"),c=s?.querySelector("[data-scene-move-summary]"),d=s?.querySelector("[data-scene-move-submit]"),u="plotline.timeline.scroll";let p=null,m=0;const h=(e,t,n)=>{const a=e?.querySelector(`[name='${CSS.escape(t)}']`);a&&(a.value=n??"")},g=e=>e?.selectedOptions?.[0]?.textContent?.trim()||"",f=e=>`“${e||"this scene"}”`,v=(e,t,n,a,r)=>t&&n&&t===n?`Move ${f(e.label)} to this new position within ${n}?`:t&&n?`Move ${f(e.label)} from ${t} to ${n}?`:`Move ${f(e.label)} ${a.toLowerCase()} ${r}?`,y=(e,s,u,p)=>{if("scene"===e)return t.classList.add("d-none"),t.querySelectorAll("[data-drag-form]").forEach(e=>e.classList.add("d-none")),n.get("scene")?.classList.remove("d-none"),l&&(l.textContent=s),c&&(c.textContent=u),d&&d.classList.toggle("d-none",s.toLowerCase().startsWith("cannot")||s.toLowerCase().startsWith("scene already")),void(i?i.show():t.classList.remove("d-none"));n.forEach((t,n)=>t.classList.toggle("d-none",n!==e)),t.classList.remove("d-none"),a.textContent=s,r.textContent=p,o.textContent=u,t.scrollIntoView({behavior:"smooth",block:"center"})},w=()=>{t.classList.add("d-none"),n.forEach(e=>e.classList.add("d-none"))},S=()=>{document.querySelectorAll(".drop-target-active, .drop-before, .drop-after, .chapter-drop-active, .drop-chapter-end").forEach(e=>e.classList.remove("drop-target-active","drop-before","drop-after","chapter-drop-active","drop-chapter-end"))};try{const t=JSON.parse(sessionStorage.getItem(u)||"null");t&&(sessionStorage.removeItem(u),requestAnimationFrame(()=>{const n=e?.querySelector(".timeline-shell");n&&(n.scrollLeft=t.left||0),window.scrollTo({top:t.top||0})}))}catch{sessionStorage.removeItem(u)}const L=e=>{try{const t=JSON.parse(e.dataTransfer.getData("application/json")||"{}");return t.type?t:p||{}}catch{return p||{}}};document.querySelectorAll("[data-drag-type][draggable='true']").forEach(e=>{e.addEventListener("dragstart",t=>((e,t)=>{const n={type:t.dataset.dragType,id:t.dataset.dragId,label:t.dataset.dragLabel||t.textContent.trim()};e.dataTransfer.effectAllowed="copyMove",e.dataTransfer.setData("application/json",JSON.stringify(n)),e.dataTransfer.setData("text/plain",`${n.type}:${n.id}`),p=n,document.body.classList.add("drag-active",`dragging-${n.type}`),t.classList.add("is-dragging")})(t,e)),e.addEventListener("dragend",()=>{e.classList.remove("is-dragging"),document.body.classList.remove("drag-active","dragging-scene","dragging-character","dragging-asset","dragging-location"),p=null,S()})}),t.querySelectorAll("[data-drag-cancel]").forEach(e=>e.addEventListener("click",w)),n.get("scene")?.addEventListener("submit",()=>{const t=e?.querySelector(".timeline-shell");try{sessionStorage.setItem(u,JSON.stringify({left:t?.scrollLeft||0,top:window.scrollY||0}))}catch{}}),e?.querySelectorAll(".timeline-scene-card[data-scene-id]").forEach(t=>{t.addEventListener("click",e=>{Date.now(){const n=L(e);["scene","character","asset"].includes(n.type)&&(e.preventDefault(),e.stopPropagation(),e.dataTransfer.dropEffect="scene"===n.type?"move":"copy",t.classList.add("drop-target-active"),t.classList.toggle("drop-before","scene"===n.type&&e.offsetX=t.clientWidth/2))}),t.addEventListener("dragleave",()=>t.classList.remove("drop-target-active","drop-before","drop-after")),t.addEventListener("drop",a=>{const r=L(a);if(!["scene","character","asset"].includes(r.type))return;a.preventDefault(),a.stopPropagation(),m=Date.now()+800,t.classList.remove("drop-target-active","drop-before","drop-after");const o=t.dataset.sceneId;if("scene"===r.type){if(r.id===o)return void y("scene","Cannot move scene","Drop a scene before or after a different scene.","Scene move");const s=n.get("scene"),i=a.offsetX{const a=t.closest("[data-chapter-drop-target]"),r=t.dataset.chapterId||a?.dataset.chapterId,o=t.dataset.chapterLabel||a?.dataset.chapterLabel||"this chapter";t.addEventListener("dragover",e=>{"scene"===L(e).type&&r&&(e.target.closest(".timeline-scene-card[data-scene-id]")||(e.preventDefault(),e.dataTransfer.dropEffect="move",t.classList.add("drop-target-active","drop-chapter-end"),a?.classList.add("chapter-drop-active")))}),t.addEventListener("dragleave",e=>{t.contains(e.relatedTarget)||(t.classList.remove("drop-target-active","drop-chapter-end"),a?.classList.remove("chapter-drop-active"))}),t.addEventListener("drop",a=>{const s=L(a);if("scene"!==s.type||!r)return;if(a.target.closest(".timeline-scene-card[data-scene-id]"))return;a.preventDefault(),a.stopPropagation(),m=Date.now()+800,S();const i=e.querySelector(`.timeline-scene-card[data-scene-id='${CSS.escape(s.id)}']`);if(i?.dataset.chapterId===r&&t.lastElementChild?.dataset?.sceneId===s.id)return void y("scene","Scene already here",`${s.label} is already at the end of ${o}.`,"Scene move");const l=n.get("scene");h(l,"SceneID",s.id),h(l,"AnchorSceneID",""),h(l,"TargetChapterID",r),h(l,"Position","End"),y("scene","Move Scene?",v(s,i?.dataset.chapterLabel||"",o,"After",o),"Scene move")})});const b=n.get("asset-dependency"),E=()=>{const e=b?.dataset.sourceLabel||"Source asset",n=b?.dataset.targetLabel||"Target asset",a=g(b?.querySelector("[name='AssetDependencyTypeID']"))||"Requires",r=g(b?.querySelector("[name='SourceRequiredStateID']"))||"the required state",o=g(b?.querySelector("[name='TargetBlockedStateID']"))||"the blocked state",s=t.querySelector("[data-asset-dependency-preview]");s&&(s.textContent=`${e} ${a.toLowerCase()} ${n}. ${e} should be ${r} before ${n} can be ${o}.`)};b?.querySelectorAll("select").forEach(e=>e.addEventListener("change",E)),document.querySelectorAll("[data-asset-drop-target], .drag-chip.asset").forEach(e=>{e.addEventListener("dragover",t=>{"asset"===L(t).type&&(t.preventDefault(),t.dataTransfer.dropEffect="copy",e.classList.add("drop-target-active"))}),e.addEventListener("dragleave",()=>e.classList.remove("drop-target-active")),e.addEventListener("drop",t=>{const n=L(t),a=e.dataset.assetId||e.dataset.dragId,r=e.dataset.assetLabel||e.dataset.dragLabel||e.textContent.trim();"asset"===n.type&&a&&(t.preventDefault(),e.classList.remove("drop-target-active"),n.id!==a?(h(b,"SourceAssetID",n.id),h(b,"TargetAssetID",a),b.dataset.sourceLabel=n.label,b.dataset.targetLabel=r,E(),y("asset-dependency","Create asset dependency",`${n.label} -> ${r}`,"Asset dependency")):y("asset-dependency","Cannot create dependency","Drop one asset onto a different asset.","Asset dependency"))})}),document.querySelectorAll("[data-drag-type='location']").forEach(e=>{e.addEventListener("dragover",t=>{"location"===L(t).type&&(t.preventDefault(),t.dataTransfer.dropEffect="copy",e.classList.add("drop-target-active"))}),e.addEventListener("dragleave",()=>e.classList.remove("drop-target-active")),e.addEventListener("drop",t=>{const a=L(t),r=e.dataset.dragId,o=e.dataset.dragLabel||e.textContent.trim();if("location"!==a.type)return;if(t.preventDefault(),e.classList.remove("drop-target-active"),a.id===r)return void y("location-relationship","Cannot create relationship","Drop one location onto a different location.","Location relationship");const s=n.get("location-relationship");h(s,"FromLocationID",a.id),h(s,"ToLocationID",r),y("location-relationship","Create location relationship",`${a.label} -> ${o}`,"Location drop")})})})(); \ No newline at end of file diff --git a/PlotLine/wwwroot/js/word-companion-host.js b/PlotLine/wwwroot/js/word-companion-host.js index b1eb968..7176cbb 100644 --- a/PlotLine/wwwroot/js/word-companion-host.js +++ b/PlotLine/wwwroot/js/word-companion-host.js @@ -215,6 +215,7 @@ let characterAliasCache = []; let lastSuggestedSceneId = null; let lastSuggestedCharacterSignature = ""; + let lastFollowSceneNotificationSignature = ""; let lastLinkedSceneTitle = ""; let lastLinkedChapterTitle = ""; let runtimeLastDebugAt = 0; @@ -929,6 +930,7 @@ hideSceneCreateLink(); setResolvedScene(sceneId, chapterId, resolutionMethod); renderCompanionData(companionData); + notifyPlotDirectorCurrentScene(sceneId, chapterId); scheduleSceneWordCountSync(); scheduleCharacterSuggestionDetection(); }; @@ -2944,6 +2946,37 @@ } }; + const notifyPlotDirectorCurrentScene = async (sceneId = resolvedSceneId, chapterId = resolvedChapterId) => { + const project = selectedProject(); + const book = selectedBook(); + const documentGuid = currentDocumentGuid(); + const numericSceneId = Number.parseInt(sceneId || "", 10); + const numericChapterId = Number.parseInt(chapterId || "", 10); + if (!project || !book || !documentGuid || !Number.isInteger(numericSceneId) || numericSceneId <= 0 || !Number.isInteger(numericChapterId) || numericChapterId <= 0) { + return; + } + + const signature = `${project.projectId}:${book.bookId}:${numericSceneId}`; + if (lastFollowSceneNotificationSignature === signature) { + return; + } + + lastFollowSceneNotificationSignature = signature; + try { + await postJson("/api/word-companion/runtime/current-scene", { + documentGuid, + projectId: project.projectId, + bookId: book.bookId, + chapterId: numericChapterId, + sceneId: numericSceneId + }); + runtimeDebug("Current scene follow event sent."); + } catch (error) { + lastFollowSceneNotificationSignature = ""; + console.debug("Unable to notify PlotDirector of current scene.", error); + } + }; + const loadRuntimeDocumentAwareness = async () => { const book = selectedBook(); if (!book || !officeReady || !wordHostAvailable || !window.Word || typeof window.Word.run !== "function") { diff --git a/PlotLine/wwwroot/js/word-companion-host.min.js b/PlotLine/wwwroot/js/word-companion-host.min.js index f93f375..46ea721 100644 --- a/PlotLine/wwwroot/js/word-companion-host.min.js +++ b/PlotLine/wwwroot/js/word-companion-host.min.js @@ -1 +1 @@ -(()=>{const e="plotdirector.word.projectId",t="plotdirector.word.bookId",n="plotdirector.word.activeTab",r="plotdirector.word.documentGuid",a="plotdirector.word.boundBookId",o="plotdirector.word.boundProjectId",c="plotdirector.word.bindingVersion",i=new Set(["scene","links","structure","diagnostics"]),s=document.querySelector(".word-companion-shell"),d=document.querySelector(".word-companion-tabs"),l=[...document.querySelectorAll("[data-tab-button]")],u=[...document.querySelectorAll("[data-tab-panel]")],p=document.querySelector("[data-first-run-wizard]"),h=document.querySelector("[data-first-run-project-select]"),m=document.querySelector("[data-first-run-book-select]"),y=document.querySelector("[data-first-run-new-book-title]"),w=document.querySelector("[data-first-run-create-book]"),f=document.querySelector("[data-first-run-scan]"),g=document.querySelector("[data-first-run-cancel]"),S=document.querySelector("[data-first-run-status]"),I=document.querySelector("[data-first-run-summary]"),C=document.querySelector("[data-first-run-character-section]"),b=document.querySelector("[data-first-run-character-status]"),k=document.querySelector("[data-first-run-character-candidates]"),v=document.querySelector("[data-first-run-character-actions]"),x=document.querySelector("[data-first-run-create-characters]"),E=document.querySelector("[data-first-run-skip-characters]"),N=document.querySelector("[data-first-run-continue]"),L=document.querySelector("[data-first-run-import-actions]"),P=document.querySelector("[data-first-run-import]"),q=document.querySelector("[data-first-run-import-cancel]"),D=document.querySelector("[data-first-run-replace-dialog]"),A=document.querySelector("[data-first-run-replace-confirm]"),T=document.querySelector("[data-first-run-replace-cancel]"),$=document.querySelector("[data-office-status]"),j=document.querySelector("[data-connection-status]"),W=document.querySelector("[data-summary-connection]"),R=document.querySelector("[data-summary-project]"),U=document.querySelector("[data-summary-book]"),M=document.querySelector("[data-project-select]"),O=document.querySelector("[data-book-select]"),H=document.querySelector("[data-project-message]"),B=document.querySelector("[data-book-message]"),G=document.querySelector("[data-refresh-current-scene]"),F=document.querySelector("[data-refresh-document]"),V=document.querySelector("[data-current-chapter]"),J=document.querySelector("[data-current-scene]"),Y=document.querySelector("[data-current-word-count]"),_=document.querySelector("[data-scene-tracking-status]"),z=document.querySelector("[data-document-message]"),K=document.querySelector("[data-sync-note]"),Q=document.querySelector("[data-document-outline]"),X=document.querySelector("[data-analyse-manuscript-structure]"),Z=document.querySelector("[data-apply-structure-sync]"),ee=document.querySelector("[data-structure-preview-status]"),te=document.querySelector("[data-structure-preview-results]"),ne=document.querySelector("[data-refresh-plotdirector-scene]"),re=document.querySelector("[data-plotdirector-scene-status]"),ae=document.querySelector("[data-anchor-status]"),oe=document.querySelector("[data-anchor-book-id]"),ce=document.querySelector("[data-anchor-chapter-id]"),ie=document.querySelector("[data-anchor-scene-id]"),se=document.querySelector("[data-attach-plotdirector-ids]"),de=document.querySelector("[data-plotdirector-scene-details]"),le=document.querySelector("[data-plotdirector-scene-title]"),ue=document.querySelector("[data-plotdirector-revision-status]"),pe=document.querySelector("[data-plotdirector-estimated-words]"),he=document.querySelector("[data-plotdirector-actual-words]"),me=document.querySelector("[data-plotdirector-blocked-status]"),ye=document.querySelector("[data-plotdirector-blocked-reason-row]"),we=document.querySelector("[data-plotdirector-blocked-reason]"),fe=document.querySelector("[data-runtime-last-sync]"),ge=document.querySelector("[data-sync-scene-progress]"),Se=document.querySelector("[data-sync-word-count]"),Ie=document.querySelector("[data-sync-plotdirector-count]"),Ce=document.querySelector("[data-sync-last-synced]"),be=document.querySelector("[data-sync-status]"),ke=document.querySelector("[data-writing-brief-block]"),ve=document.querySelector("[data-writing-brief]"),xe=document.querySelector("[data-plotdirector-link-groups]"),Ee=document.querySelector("[data-character-chips]"),Ne=document.querySelector("[data-asset-chips]"),Le=(document.querySelector("[data-location-chips]"),document.querySelector("[data-primary-location-select]")),Pe=document.querySelector("[data-save-scene-links]"),qe=document.querySelector("[data-scene-links-status]"),De=document.querySelector("[data-links-editing-scene]"),Ae=document.querySelector("[data-chapter-create-link]"),Te=document.querySelector("[data-chapter-create-link-chapter]"),$e=document.querySelector("[data-create-plotdirector-chapter]"),je=document.querySelector("[data-link-existing-chapter]"),We=document.querySelector("[data-chapter-create-link-status]"),Re=document.querySelector("[data-scene-create-link]"),Ue=document.querySelector("[data-create-link-chapter]"),Me=document.querySelector("[data-create-link-scene]"),Oe=document.querySelector("[data-create-plotdirector-scene]"),He=document.querySelector("[data-link-existing-scene]"),Be=document.querySelector("[data-create-link-status]"),Ge=document.querySelector("[data-link-existing-dialog]"),Fe=document.querySelector("[data-link-scene-search]"),Ve=document.querySelector("[data-link-scene-options]"),Je=document.querySelector("[data-link-selected-scene]"),Ye=document.querySelector("[data-link-dialog-cancel]"),_e=document.querySelector("[data-link-dialog-status]"),ze=document.querySelector("[data-create-scene-dialog]"),Ke=document.querySelector("[data-create-dialog-scene]"),Qe=document.querySelector("[data-create-dialog-chapter]"),Xe=document.querySelector("[data-create-dialog-confirm]"),Ze=document.querySelector("[data-create-dialog-cancel]"),et=document.querySelector("[data-link-existing-chapter-dialog]"),tt=document.querySelector("[data-link-chapter-search]"),nt=document.querySelector("[data-link-chapter-options]"),rt=document.querySelector("[data-link-selected-chapter]"),at=document.querySelector("[data-link-chapter-dialog-cancel]"),ot=document.querySelector("[data-link-chapter-dialog-status]"),ct=document.querySelector("[data-create-chapter-dialog]"),it=document.querySelector("[data-create-chapter-dialog-chapter]"),st=document.querySelector("[data-create-chapter-dialog-book]"),dt=document.querySelector("[data-create-chapter-dialog-confirm]"),lt=document.querySelector("[data-create-chapter-dialog-cancel]"),ut=document.querySelector("[data-apply-structure-sync-dialog]"),pt=document.querySelector("[data-apply-structure-sync-summary]"),ht=document.querySelector("[data-apply-structure-sync-confirm]"),mt=document.querySelector("[data-apply-structure-sync-cancel]"),yt=document.querySelector("[data-resolve-project-id]"),wt=document.querySelector("[data-resolve-project-title]"),ft=document.querySelector("[data-resolve-book-id]"),gt=document.querySelector("[data-resolve-book-title]"),St=document.querySelector("[data-resolve-detected-chapter]"),It=document.querySelector("[data-resolve-detected-scene]"),Ct=document.querySelector("[data-resolve-request-chapter]"),bt=document.querySelector("[data-resolve-request-scene]"),kt=document.querySelector("[data-resolve-result]"),vt=document.querySelector("[data-resolve-chapter-id]"),xt=document.querySelector("[data-resolve-scene-id]"),Et=document.querySelector("[data-run-diagnostics]"),Nt=document.querySelector("[data-diagnostic-host]"),Lt=document.querySelector("[data-diagnostic-platform]"),Pt=document.querySelector("[data-diagnostic-ready]"),qt=document.querySelector("[data-diagnostic-word-api]"),Dt=document.querySelector("[data-diagnostic-last-scan]"),At=document.querySelector("[data-diagnostic-last-error]"),Tt=document.querySelector("[data-diagnostic-anchor-type]"),$t=document.querySelector("[data-diagnostic-stored-scene-id]"),jt=document.querySelector("[data-diagnostic-stored-chapter-id]"),Wt=document.querySelector("[data-diagnostic-resolution-method]"),Rt=document.querySelector("[data-diagnostic-paragraphs]"),Ut=document.querySelector("[data-diagnostic-heading1]"),Mt=document.querySelector("[data-diagnostic-heading2]"),Ot="true"===s?.dataset.authenticated;let Ht=[],Bt=[],Gt=!1,Ft=!1,Vt="Unknown",Jt="Unknown",Yt="",_t="",zt=null,Kt=null,Qt=null,Xt=null,Zt=null,en=null,tn="",nn="Title Match",rn=!1,an=[],on=null,cn=null,sn=[],dn=null,ln=null,un=null,pn=null,hn=null,mn=null,yn=null,wn=null,fn=null,gn=null,Sn=[],In=!1,Cn=!1,bn=0,kn=!1,vn=!1,xn=!1,En=null,Nn="Manual",Ln=!1,Pn=null,qn=!1,Dn=0,An=!1;const Tn=1200;let $n=!1,jn=!1,Wn=null,Rn=!1,Un=!1,Mn=null,On=null,Hn=null,Bn=!1,Gn=!1,Fn=null,Vn="",Jn=[],Yn=null,_n="",zn="",Kn="",Qn=0,Xn={characters:[],assets:[],locations:[],primaryLocationId:null};const Zn=e=>{const t=Date.now();t-Qn<1e3||(Qn=t,console.debug(`[Word Companion Runtime] ${e}`))},er=e=>{$&&($.textContent=e)},tr=(e,t=!0)=>{const r=i.has(e)&&l.some(t=>t.dataset.tabButton===e)?e:"scene";for(const e of l){const t=e.dataset.tabButton===r;e.classList.toggle("is-active",t),e.setAttribute("aria-selected",t?"true":"false")}for(const e of u){const t=e.dataset.tabPanel===r;e.classList.toggle("is-active",t),e.hidden=!t}t&&((e,t)=>{try{t?window.localStorage.setItem(e,String(t)):window.localStorage.removeItem(e)}catch{}})(n,r)},nr=()=>{const e=(e=>{try{return window.localStorage.getItem(e)||""}catch{return""}})(n);tr(i.has(e)?e:"scene",!1)},rr=e=>{j&&(j.textContent=e),W&&(W.textContent=e)},ar=e=>{H&&(H.textContent=e)},or=e=>{B&&(B.textContent=e)},cr=e=>{z&&(z.textContent=e)},ir=e=>{re&&(re.textContent=e)},sr=e=>{const t=t=>Object.prototype.hasOwnProperty.call(e,t);t("anchorType")&&Qr(Tt,xr(e.anchorType)),t("storedSceneId")&&Qr($t,xr(e.storedSceneId)),t("storedChapterId")&&Qr(jt,xr(e.storedChapterId)),t("resolutionMethod")&&Qr(Wt,xr(e.resolutionMethod))},dr=()=>{const e=ia(),t=Number.isInteger(Zt)&&Zt>0&&Xt===Zt,n=!Number.isInteger(en)||en<=0||Qt===en,r=t&&n;Qr(ae,r?"Attached to PlotDirector":"Not attached"),Qr(oe,e?.bookId?String(e.bookId):"-"),Qr(ce,Number.isInteger(en)&&en>0?String(en):"-"),Qr(ie,Number.isInteger(Zt)&&Zt>0?String(Zt):"-"),se&&(se.disabled=!Zt||r&&!rn,se.textContent=Xt&&!r?"Reattach PlotDirector IDs":"Attach PlotDirector IDs"),sr({anchorType:nn||"Title Match",storedSceneId:Xt,storedChapterId:Qt,resolutionMethod:tn})},lr=(e,t,n,r=null,a=null,o=null)=>{const c=e||"",i=t||"",s=Number.isInteger(n)?n:null,d=Number.isInteger(o)&&o>0?o:null,l=Number.isInteger(r)&&r>0?r:null,u=Number.isInteger(a)&&a>0?a:null,p=Yt===c&&_t===i&&zt===s&&Kt===d&&Qt===l&&Xt===u;Yt=e||"",_t=t||"",zt=Number.isInteger(n)?n:null,Kt=Number.isInteger(o)&&o>0?o:null,Qt=Number.isInteger(r)&&r>0?r:null,Xt=Number.isInteger(a)&&a>0?a:null,p||(V&&(V.textContent=e||"Not detected"),J&&(J.textContent=t||"Not detected"),Y&&(Y.textContent=Number.isInteger(n)?String(n):"-"),Qr(Se,Number.isInteger(n)?String(n):"-"),dr())},ur=()=>{Wn&&(window.clearTimeout(Wn),Wn=null)},pr=(e,t)=>{e&&(e.hidden=t)},hr=e=>{Qr(be,e)},mr=e=>{Qr(ee,e)},yr=(e="Select a project and book to analyse manuscript structure.")=>{if(un=null,te){te.innerHTML="";const e=document.createElement("p");e.textContent="No preview generated.",te.append(e)}mr(e),fr()},wr=(e=un)=>((e=un)=>ja.flatMap(t=>Array.isArray(e?.[t.key])?e[t.key]:[]))(e).filter(e=>"couldLink"===e.category||"wouldCreateChapters"===e.category||"wouldCreateScenes"===e.category),fr=()=>{Z&&(Z.disabled=xn||0===wr().length)},gr=()=>{X&&(X.disabled=xn||!ca()||!ia()),fr()},Sr=()=>{De&&(De.textContent=Zt?`Editing links for: ${zn||_t||"Current scene"}`:"Link a PlotDirector scene first.")},Ir=()=>{const e=Ln||!Zt,t=e||!en||Rn;ge&&(ge.disabled=t),Pe&&(Pe.disabled=e),Le&&(Le.disabled=e);for(const t of[Ee,Ne])for(const n of t?[...t.querySelectorAll("input[type='checkbox']")]:[])n.disabled=e},Cr=e=>{"Live"!==e&&"Manual"!==e||(Nn=e),Qr(_,e||Nn||"Manual")},br=(e,t="")=>{Ln=!!e,Ln&&(ur(),Eo()),Qr(_,Ln?"Stale":Nn),Ir(),t&&(cr(t),qr(t))},kr=(e,t=null,n="")=>{Zt=Number.isInteger(e)&&e>0?e:null,en=Number.isInteger(t)&&t>0?t:null,tn=n||"",Zt!==Mn&&(On=null),Zt||(ur(),Eo()),Ir(),hr(Ln?"Refresh Current Scene before syncing.":Zt?"Ready to sync.":"No resolved PlotDirector scene."),qr(Ln?"Refresh Current Scene before saving.":Zt?"Ready to save.":"Link a PlotDirector scene first."),Sr(),dr()},vr=e=>{G&&(G.disabled=e,G.textContent=e?"Refreshing...":"Refresh Current Scene")},xr=e=>null==e||""===e?"-":String(e),Er=e=>{if(!e)return"-";const t=e instanceof Date?e:new Date(e);if(Number.isNaN(t.getTime()))return"-";const n=new Date;return`Last synced: ${t.toDateString()===n.toDateString()?"Today":t.toLocaleDateString()} ${t.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"})}`},Nr=e=>{hn=e||null;const t=hn?.lastSyncUtc||hn?.manuscriptDocument?.lastSyncUtc;Qr(fe,Er(t)),Qr(Ce,Er(t))},Lr=()=>{mn=null,yn=null,wn=null,No(),Nr(null)},Pr=()=>{yn=null,wn=null},qr=e=>{Qr(qe,e)},Dr=e=>{Qr(Be,e)},Ar=e=>{Qr(We,e)},Tr=()=>!!ia()&&!!Yt&&!en,$r=()=>!!ia()&&!!_t&&Number.isInteger(en)&&en>0,jr=()=>{pr(Ae,!0),Ar(""),$e&&($e.disabled=!0,$e.textContent="Create Chapter in PlotDirector"),je&&(je.disabled=!0,je.textContent="Link to Existing Chapter")},Wr=(e="")=>{Qr(Te,xr(Yt)),pr(Ae,!1),Ar(e);const t=Tr();$e&&($e.disabled=!t,$e.textContent="Create Chapter in PlotDirector"),je&&(je.disabled=!t,je.textContent="Link to Existing Chapter")},Rr=()=>{pr(Re,!0),Dr(""),Oe&&(Oe.disabled=!0,Oe.textContent="Create Scene in PlotDirector"),He&&(He.disabled=!0,He.textContent="Link to Existing Scene")},Ur=(e="")=>{Qr(Ue,xr(Yt)),Qr(Me,xr(_t)),pr(Re,!1),Dr(e);const t=$r();Oe&&(Oe.disabled=!t,Oe.textContent="Create Scene in PlotDirector"),He&&(He.disabled=!t,He.textContent="Link to Existing Scene")},Mr=e=>{ir(e),pr(de,!0),pr(ke,!0),pr(xe,!1),jr(),Rr(),tn="",zn="",Kn="",nn=Xt?"SceneID Anchor":Qt?"ChapterID Anchor":"Title Match",rn=!1,Xn={characters:[],assets:[],locations:[],primaryLocationId:null},Hr(Ee,[],"character"),Hr(Ne,[],"asset"),Br([],null,!1),kr(null),Qr(Ie,"-"),Qr(le,"-"),Qr(ue,"-"),Qr(pe,"-"),Qr(he,"-"),Qr(me,"-"),Qr(we,"-"),pr(ye,!0),dr(),Sr()},Or=(e,t)=>"asset"===t?e?.assetId||e?.AssetId||e?.storyAssetId||e?.StoryAssetId||0:"location"===t?e?.locationId||e?.LocationId||0:e?.characterId||e?.CharacterId||0,Hr=(e,t,n,r=!1)=>{if(!e)return;e.innerHTML="";const a=Array.isArray(t)?t:[];if(0===a.length){const t=document.createElement("p");return t.className="word-companion-empty-list",t.textContent="None",void e.append(t)}for(const t of a){const a=Number.parseInt(Or(t,n),10);if(!Number.isInteger(a)||a<=0)continue;const o=document.createElement("label");o.className="word-companion-check-item";const c=document.createElement("input");c.type="checkbox",c.value=String(a),c.checked=!!t.linked,c.disabled=!r;const i=document.createElement("span");i.textContent=t.name||"Unnamed",o.append(c,i),e.append(o)}},Br=(e,t,n=!1)=>{if(!Le)return;Le.innerHTML="";const r=document.createElement("option");r.value="",r.textContent="None",Le.append(r);const a=Number.parseInt(t||"",10);for(const t of Array.isArray(e)?e:[]){const e=Number.parseInt(Or(t,"location"),10);if(!Number.isInteger(e)||e<=0)continue;const n=document.createElement("option");n.value=String(e),n.textContent=t.name||"Unnamed",n.selected=e===a,Le.append(n)}Le.disabled=!n},Gr=e=>String(e||"").trim().replace(/\s+/g," "),Fr=(e,t)=>{const n=Gr(e);if(!n)return"";const r=new RegExp(`^${"scene"===t?"scene":"chapter"}\\s+(?:\\d+|[ivxlcdm]+|one|two|three|four|five|six|seven|eight|nine|ten|eleven|twelve|thirteen|fourteen|fifteen|sixteen|seventeen|eighteen|nineteen|twenty)\\s*(?::|-|\\u2013|\\u2014)\\s*`,"i");return Gr(n.replace(r,""))||n},Vr=e=>{const t=t=>Object.prototype.hasOwnProperty.call(e,t);t("projectId")&&Qr(yt,xr(e.projectId)),t("projectTitle")&&Qr(wt,xr(e.projectTitle)),t("bookId")&&Qr(ft,xr(e.bookId)),t("bookTitle")&&Qr(gt,xr(e.bookTitle)),t("detectedChapter")&&Qr(St,xr(e.detectedChapter)),t("detectedScene")&&Qr(It,xr(e.detectedScene)),t("requestChapter")&&Qr(Ct,xr(e.requestChapter)),t("requestScene")&&Qr(bt,xr(e.requestScene)),t("result")&&Qr(kt,xr(e.result)),t("chapterId")&&Qr(vt,xr(e.chapterId)),t("sceneId")&&Qr(xt,xr(e.sceneId))},Jr=async e=>{if(wn===e&&Array.isArray(yn?.chapters))return yn.chapters;const t=await oo(`/api/word-companion/books/${e}/structure`);return wn=e,yn=t||null,Array.isArray(t?.chapters)?t.chapters:[]},Yr=async e=>{const t=await oo(`/api/word-companion/books/${e}/chapters`);return Array.isArray(t?.chapters)?t.chapters:[]},_r=e=>{if(Number.isInteger(en)&&en>0){const t=e.find(e=>e.chapterId===en);if(t)return t}const t=Fr(Yt,"chapter").toLocaleLowerCase();return t&&e.find(e=>Fr(e.title,"chapter").toLocaleLowerCase()===t)||null},zr=async()=>{const e=ia();return e?_r(await Jr(e.bookId)):null},Kr=async(e,t,n,r,a)=>{const o=await oo(`/api/word-companion/scenes/${t}/companion`);try{o.revisionStatus=await(async(e,t)=>{const n=await oo(`/api/word-companion/books/${e}/structure`),r=Array.isArray(n?.chapters)?n.chapters:[];for(const e of r){const n=(Array.isArray(e.scenes)?e.scenes:[]).find(e=>e.sceneId===t);if(n)return n.revisionStatus||""}return""})(e,t)}catch{o.revisionStatus=""}var c;nn=a||"Title Match",rn=!1,br(!1),ir("Linked to PlotDirector"),cr(""),jr(),Rr(),kr(t,n,r),c=o,zn=c?.sceneTitle||_t||"",Kn=c?.chapterTitle||Yt||"",Qr(le,xr(c?.sceneTitle)),Qr(ue,xr(c?.revisionStatus||c?.revisionStatusName||"Not provided")),Qr(pe,xr(c?.estimatedWords)),Qr(he,xr(c?.actualWords)),Qr(Ie,xr(c?.actualWords)),Qr(me,c?.blocked?"Blocked":"Not blocked"),c?.blockedReason?(Qr(we,c.blockedReason),pr(ye,!1)):(Qr(we,"-"),pr(ye,!0)),ve&&(ve.textContent=c?.writingBrief||"No writing brief has been added for this scene."),Xn={characters:Array.isArray(c?.characters)?c.characters:[],assets:Array.isArray(c?.assets)?c.assets:[],locations:Array.isArray(c?.locations)?c.locations:[],primaryLocationId:c?.primaryLocationId??null},Hr(Ee,Xn.characters,"character",!!Zt&&!Ln),Hr(Ne,Xn.assets,"asset",!!Zt&&!Ln),Br(Xn.locations,Xn.primaryLocationId,!!Zt&&!Ln),Sr(),qr(Ln?"Refresh Current Scene before saving.":Zt?"Ready to save.":"No resolved PlotDirector scene."),pr(de,!1),pr(ke,!1),pr(xe,!1),xo(),Do()},Qr=(e,t)=>{if(e){const n=null==t?"":String(t);e.textContent!==n&&(e.textContent=n)}},Xr=e=>{const t=t=>Object.prototype.hasOwnProperty.call(e,t);t("host")&&Qr(Nt,e.host),t("platform")&&Qr(Lt,e.platform),t("ready")&&Qr(Pt,e.ready),t("wordApi")&&Qr(qt,e.wordApi),t("lastScan")&&Qr(Dt,e.lastScan),t("lastError")&&Qr(At,e.lastError),t("paragraphs")&&Qr(Rt,e.paragraphs),t("heading1")&&Qr(Ut,e.heading1),t("heading2")&&Qr(Mt,e.heading2)},Zr=e=>{const t=[];return e?.name&&t.push(e.name),e?.code&&e.code!==e.name&&t.push(e.code),e?.message&&t.push(e.message),e?.debugInfo?.errorLocation&&t.push(`Location: ${e.debugInfo.errorLocation}`),t.length>0?t.join(": "):String(e)},ea=async()=>{if(!window.Office||"function"!=typeof window.Office.onReady)return Gt=!1,Ft=!1,Vt="Unavailable",Jt="Unavailable",Xr({host:Vt,platform:Jt,ready:"No",wordApi:"No"}),null;const e=await window.Office.onReady();return Gt=!0,Vt=e?.host||"Unknown",Jt=e?.platform||"Unknown",Ft=!!window.Word&&!!window.Office.HostType&&e?.host===window.Office.HostType.Word,Xr({host:Vt,platform:Jt,ready:"Yes",wordApi:Ft?"Yes":"No"}),e},ta=e=>{try{const t=window.localStorage.getItem(e),n=Number.parseInt(t||"",10);return Number.isInteger(n)&&n>0?n:null}catch{return null}},na=(e,t)=>{try{t?window.localStorage.setItem(e,String(t)):window.localStorage.removeItem(e)}catch{}},ra=(e,t)=>{if(!e)return;e.innerHTML="";const n=document.createElement("option");n.value="",n.textContent=t,e.append(n),e.disabled=!0},aa=(e,t,n,r,a)=>{if(!e)return;e.innerHTML="";const o=document.createElement("option");o.value="",o.textContent=t,e.append(o);for(const t of n){const n=document.createElement("option");n.value=String(t[r]),n.textContent=t[a],e.append(n)}e.disabled=0===n.length},oa=e=>{const t=String(e?.title||"").trim(),n=String(e?.subtitle||"").trim();return n?`${t}: ${n}`:t},ca=()=>{const e=Number.parseInt(M?.value||"",10);return Ht.find(t=>t.projectId===e)||null},ia=()=>{const e=Number.parseInt(O?.value||"",10);return Bt.find(t=>t.bookId===e)||null},sa=()=>{const e=Number.parseInt(h?.value||"",10);return Ht.find(t=>t.projectId===e)||null},da=()=>{const e=Number.parseInt(m?.value||"",10);return Bt.find(t=>t.bookId===e)||null},la=e=>Qr(S,e),ua=()=>{const e=sa(),t=da(),n=Cn&&Date.now()-bn>=750;f&&(f.disabled=!e||!t||kn),w&&(w.disabled=!e||!String(y?.value||"").trim()||kn),P&&(P.disabled=!fn?.canImport||!gn||kn),x&&(x.disabled=!n||vn||0===ya().length)},pa=e=>{pr(p,!e),pr(d,e);for(const t of u)pr(t,!!e||"scene"!==t.dataset.tabPanel&&!t.classList.contains("is-active"));e||nr()},ha=()=>{if(!h)return;if(0===Ht.length)return void ra(h,"No projects available.");aa(h,"Choose a project",Ht,"projectId","title");const e=Number.parseInt(M?.value||"",10);Number.isInteger(e)&&e>0&&(h.value=String(e))},ma=(e="Select a Project and Book to begin.")=>{fn=null,gn=null,Sn=[],In=!1,Cn=!1,bn=0,pr(I,!0),pr(L,!0),pr(C,!0),pr(v,!0),I&&(I.innerHTML=""),k&&(k.innerHTML=""),Qr(b,""),la(e),ua()},ya=()=>k?[...k.querySelectorAll("input[type='checkbox']:checked")].map(e=>String(e.value||"").trim()).filter(Boolean):[],wa=e=>{if(Sn=Array.isArray(e)?e:[],C&&k){if(k.innerHTML="",pr(C,!1),pr(v,!In||0===Sn.length),pr(x,!1),pr(E,!1),pr(N,!0),0===Sn.length)return Qr(b,"No likely major characters found."),void ua();Qr(b,`${Sn.length} likely major characters found.`);for(const e of Sn){const t=document.createElement("label");t.className="word-companion-character-candidate";const n=document.createElement("input");n.type="checkbox",n.value=e.text||"",n.checked="high"===String(e.confidence||"").trim().toLowerCase(),n.addEventListener("change",ua);const r=document.createElement("strong");r.textContent=e.text||"";const a=document.createElement("em"),o=String(e.reason||"").trim();a.textContent=o?`${Number(e.mentionCount||0).toLocaleString()} mentions · ${o}`:`${Number(e.mentionCount||0).toLocaleString()} mentions`;const c=document.createElement("span");c.className="word-companion-character-candidate-text",c.append(r,a),t.append(n,c),k.append(t)}ua()}},fa=()=>{const e=window.Office?.context?.document?.settings;if(!e)return null;const t=String(e.get(r)||"").trim(),n=Number.parseInt(e.get(a)||"",10),i=Number.parseInt(e.get(o)||"",10),s=Number.parseInt(e.get(c)||"",10);return!t||!Number.isInteger(n)||n<=0||!Number.isInteger(i)||i<=0?null:{documentGuid:t,bookId:n,projectId:i,bindingVersion:Number.isInteger(s)&&s>0?s:1}},ga=()=>pn?.documentGuid?pn.documentGuid:window.crypto?.randomUUID?window.crypto.randomUUID():"10000000-1000-4000-8000-100000000000".replace(/[018]/g,e=>(Number(e)^16*Math.random()>>Number(e)/4).toString(16)),Sa=()=>pn?.documentGuid||fa()?.documentGuid||"",Ia=()=>{const e=ca(),t=ia();R&&(R.textContent=e?.title||"(Not connected)"),U&&(U.textContent=t?oa(t):"(Not connected)"),K&&(K.textContent=t?"":"Select a PlotDirector book before refreshing."),gr()},Ca=e=>String(e?.styleBuiltIn||e?.style||"").replace(/\s+/g,"").toLowerCase(),ba=(e,t)=>{const n=Ca(e);return n===`heading${t}`||n.endsWith(`.heading${t}`)||n.includes(`heading${t}`)},ka=e=>String(e||"").trim().split(/\s+/).filter(Boolean).length,va=(e,t)=>{const n=String(e||"").match(new RegExp(`^${t}-(\\d+)$`,"i"));if(!n)return null;const r=Number.parseInt(n[1],10);return Number.isInteger(r)&&r>0?r:null},xa=e=>{try{return Array.isArray(e?.contentControls?.items)?e.contentControls.items:[]}catch(e){return console.warn("Word paragraph content controls were not available.",e),[]}},Ea=(e,t)=>{const n=xa(e);for(const e of n){const n=va(e.tag,t);if(n)return n}return null},Na=(e,t)=>{const n=[];let r=0,a=0,o=null,c=null;e.forEach((e,t)=>{const i=String(e.text||"").trim();if(i){if(ba(e,1))return r+=1,o={index:n.length+1,paragraphIndex:t,title:i,anchorId:Ea(e,"PD-CHAPTER"),scenes:[]},n.push(o),void(c=null);if(ba(e,2)){if(a+=1,!o)return;return c={index:o.scenes.length+1,paragraphIndex:t,title:i,anchorId:Ea(e,"PD-SCENE"),wordCount:0},void o.scenes.push(c)}c&&(c.wordCount+=ka(i))}});const i=t.find(e=>String(e.text||"").trim()),s=i?e.findIndex(e=>{return t=e,n=i,String(t?.text||"").trim()===String(n?.text||"").trim()&&Ca(t)===Ca(n);var t,n}):-1,d=s>=0&&n.filter(e=>e.paragraphIndex<=s).at(-1)||null,l=d&&s>=0&&d.scenes.filter(e=>e.paragraphIndex<=s).at(-1)||null;return{chapters:n,currentChapter:d,currentScene:l,paragraphCount:e.length,heading1Count:r,heading2Count:a}},La=new Set(["***","###"]),Pa=(e,t)=>{const n=String(e?.text||"").trim();return{index:t,text:n,styleBuiltIn:e?.styleBuiltIn||"",style:e?.style||"",wordCount:ka(n),chapterAnchorId:null,sceneAnchorId:null}},qa=(e,t)=>{e&&(e.endParagraphIndex=t)},Da=(e,t)=>{e&&(e.endParagraphIndex=t,qa(e.scenes.at(-1),t))},Aa=(e,t)=>{const n=(t||[]).find(e=>String(e.text||"").trim());if(!e||!n)return e?.currentParagraphIndex??-1;const r=e.paragraphs.filter(e=>((e,t)=>String(e?.text||"").trim()===String(t?.text||"").trim()&&Ca(e)===Ca(t))(e,n)).map(e=>e.index);return 0===r.length?e.currentParagraphIndex??-1:Number.isInteger(e.currentParagraphIndex)?r.reduce((t,n)=>Math.abs(n-e.currentParagraphIndex){if(!mn)return!1;const t=((e,t)=>!e||!Number.isInteger(t)||t<0?null:e.chapters.filter(e=>e.startParagraphIndex<=t).at(-1)||null)(mn,e),n=((e,t)=>!e||!Number.isInteger(t)||t<0?null:e.scenes.filter(e=>e.startParagraphIndex<=t).at(-1)||null)(t,e),r=t?.startParagraphIndex!==mn.currentChapter?.startParagraphIndex||n?.startParagraphIndex!==mn.currentScene?.startParagraphIndex||t?.anchorId!==mn.currentChapter?.anchorId||n?.anchorId!==mn.currentScene?.anchorId;return mn.currentParagraphIndex=e,mn.currentChapter=t,mn.currentScene=n,!!r&&(lr(t?.title,n?.title,n?.wordCount,t?.anchorId,n?.anchorId,t?.index),r)},$a=e=>{if(!Q)return;if(Q.innerHTML="",0===e.chapters.length){const e=document.createElement("p");return e.textContent="No chapters detected. Use Heading 1 for chapter titles.",void Q.append(e)}if(!e.chapters.some(e=>e.scenes.length>0)){const e=document.createElement("p");e.textContent="No scenes detected. Use Heading 2 for scene titles.",Q.append(e)}for(const t of e.chapters){const e=document.createElement("div");e.className="word-companion-outline-chapter";const n=document.createElement("strong");if(n.textContent=t.title,e.append(n),t.scenes.length>0){const n=document.createElement("ul");for(const e of t.scenes){const t=document.createElement("li");t.textContent=e.title,n.append(t)}e.append(n)}Q.append(e)}},ja=[{key:"alreadyLinked",title:"Already Linked"},{key:"couldLink",title:"Could Link"},{key:"wouldCreateChapters",title:"Would Create Chapters"},{key:"wouldCreateScenes",title:"Would Create Scenes"},{key:"manualReview",title:"Manual Review Required"}],Wa={alreadyLinked:"Already Linked",couldLink:"Could Link",wouldCreateChapter:"Would Create Chapter",wouldCreateScene:"Would Create Scene",manualReview:"Manual Review Required"},Ra={alreadyLinked:"✓",couldLink:"~",wouldCreateChapter:"+",wouldCreateScene:"+",manualReview:"?"},Ua=(e,t)=>Fr(e,t).toLocaleLowerCase(),Ma=({category:e,action:t,type:n,wordTitle:r,match:a="",anchorStatus:o="None",matches:c=[],pdChapter:i=null,pdScene:s=null,wordChapter:d=null,wordScene:l=null,parentItem:u=null})=>({id:`${n}-${d?.index||0}-${l?.index||0}-${d?.paragraphIndex??l?.paragraphIndex??0}`,category:e,action:t,type:n,wordTitle:r,match:a,anchorStatus:o,matches:c,pdChapter:i,pdScene:s,wordChapter:d,wordScene:l,parentItem:u,result:"Pending",error:""}),Oa=(e,t)=>{Array.isArray(e[t.category])&&e[t.category].push(t)},Ha=e=>Array.isArray(e?.scenes)?e.scenes:[],Ba=(e,t,n)=>{const r=e.anchorId?`PD-CHAPTER-${e.anchorId}`:"None";if(e.anchorId){const a=t.find(t=>t.chapterId===e.anchorId);if(a){const t=Ma({category:"alreadyLinked",action:"alreadyLinked",type:"Chapter",wordTitle:e.title,match:`Chapter ${a.chapterId}: ${a.title}`,anchorStatus:r,pdChapter:a,wordChapter:e});return Oa(n,t),t}const o=Ma({category:"manualReview",action:"manualReview",type:"Chapter",wordTitle:e.title,anchorStatus:`${r} not found`,matches:[],pdChapter:null,wordChapter:e});return Oa(n,o),o}const a=t.filter(t=>Ua(t.title,"chapter")===Ua(e.title,"chapter"));if(1===a.length){const t=Ma({category:"couldLink",action:"couldLink",type:"Chapter",wordTitle:e.title,match:`Chapter ${a[0].chapterId}: ${a[0].title}`,anchorStatus:r,pdChapter:a[0],wordChapter:e});return Oa(n,t),t}if(a.length>1){const t=Ma({category:"manualReview",action:"manualReview",type:"Chapter",wordTitle:e.title,anchorStatus:r,matches:a.map(e=>`Chapter ${e.chapterId}: ${e.title}`),pdChapter:null,wordChapter:e});return Oa(n,t),t}const o=Ma({category:"wouldCreateChapters",action:"wouldCreateChapter",type:"Chapter",wordTitle:e.title,anchorStatus:r,pdChapter:null,wordChapter:e});return Oa(n,o),o},Ga=(e,t,n,r)=>{const a=e.anchorId?`PD-SCENE-${e.anchorId}`:"None";if(e.anchorId){const o=((e,t)=>{for(const n of e){const e=Ha(n).find(e=>e.sceneId===t);if(e)return{chapter:n,scene:e}}return null})(n,e.anchorId);return o?void Oa(r,Ma({category:"alreadyLinked",action:"alreadyLinked",type:"Scene",wordTitle:e.title,match:`Scene ${o.scene.sceneId}: ${o.scene.title}`,anchorStatus:a,pdChapter:o.chapter,pdScene:o.scene,wordChapter:t?.wordChapter,wordScene:e,parentItem:t})):void Oa(r,Ma({category:"manualReview",action:"manualReview",type:"Scene",wordTitle:e.title,anchorStatus:`${a} not found`,wordChapter:t?.wordChapter,wordScene:e,parentItem:t}))}if(!t?.pdChapter&&"manualReview"===t?.category)return void Oa(r,Ma({category:"manualReview",action:"manualReview",type:"Scene",wordTitle:e.title,anchorStatus:a,matches:["Parent chapter requires manual review."],wordChapter:t?.wordChapter,wordScene:e,parentItem:t}));if(!t?.pdChapter)return void Oa(r,Ma({category:"wouldCreateScenes",action:"wouldCreateScene",type:"Scene",wordTitle:e.title,anchorStatus:a,wordChapter:t?.wordChapter,wordScene:e,parentItem:t}));const o=Ha(t.pdChapter).filter(t=>Ua(t.title,"scene")===Ua(e.title,"scene"));1!==o.length?o.length>1?Oa(r,Ma({category:"manualReview",action:"manualReview",type:"Scene",wordTitle:e.title,anchorStatus:a,matches:o.map(e=>`Scene ${e.sceneId}: ${e.title}`),wordChapter:t.wordChapter,wordScene:e,parentItem:t})):Oa(r,Ma({category:"wouldCreateScenes",action:"wouldCreateScene",type:"Scene",wordTitle:e.title,anchorStatus:a,pdChapter:t.pdChapter,wordChapter:t.wordChapter,wordScene:e,parentItem:t})):Oa(r,Ma({category:"couldLink",action:"couldLink",type:"Scene",wordTitle:e.title,match:`Scene ${o[0].sceneId}: ${o[0].title}`,anchorStatus:a,pdChapter:t.pdChapter,pdScene:o[0],wordChapter:t.wordChapter,wordScene:e,parentItem:t}))},Fa=e=>{const t=document.createElement("article");t.className="word-companion-preview-item";const n=document.createElement("strong");n.textContent=`${Ra[e.action]||""} ${e.type}: ${e.wordTitle}`,t.append(n);const r=document.createElement("span");if(r.textContent=`Anchor: ${e.anchorStatus||"None"}`,t.append(r),e.match){const n=document.createElement("span");n.textContent=`Match: ${e.match}`,t.append(n)}if(Array.isArray(e.matches)&&e.matches.length>0){const n=document.createElement("div");n.className="word-companion-preview-matches";const r=document.createElement("span");r.textContent="Matches:",n.append(r);const a=document.createElement("ul");for(const t of e.matches){const e=document.createElement("li");e.textContent=t,a.append(e)}n.append(a),t.append(n)}const a=document.createElement("span");if(a.textContent=`Action: ${Wa[e.action]||e.action}`,t.append(a),e.result&&"Pending"!==e.result){const n=document.createElement("span");n.textContent=e.error?`Result: ${e.result} - ${e.error}`:`Result: ${e.result}`,t.append(n)}return t},Va=e=>{if(te){te.innerHTML="";for(const t of ja){const n=document.createElement("section");n.className="word-companion-preview-group";const r=document.createElement("strong");r.textContent=t.title,n.append(r);const a=Array.isArray(e?.[t.key])?e[t.key]:[];if(0===a.length){const e=document.createElement("p");e.className="word-companion-empty-list",e.textContent="None",n.append(e)}else for(const e of a)n.append(Fa(e));te.append(n)}fr()}},Ja=async e=>{const t=e.document.body.paragraphs,n=e.document.getSelection().paragraphs;t.load("text,styleBuiltIn,style"),n.load("text,styleBuiltIn,style"),await e.sync();try{for(const e of t.items)(ba(e,1)||ba(e,2))&&e.contentControls.load("items/tag,title");await e.sync()}catch(e){console.warn("Unable to load Word heading content controls. Continuing without PlotDirector anchors.",e)}const r=Na(t.items,n.items);return r.bodyParagraphs=t.items,r},Ya=async(e,t)=>{const n=e.document.body.paragraphs,r=e.document.getSelection().paragraphs;n.load("text,styleBuiltIn,style"),r.load("text,styleBuiltIn,style"),await e.sync();const a=((e,t)=>{const n=e.map(Pa),r=[];let a=0,o=0,c=null,i=null,s=0;const d=(e,t=null,n=null)=>c?(qa(i,e.index-1),i={index:c.scenes.length+1,paragraphIndex:e.index,startParagraphIndex:e.index,endParagraphIndex:e.index,title:t||`Scene ${c.scenes.length+1}`,anchorId:n,wordCount:0},c.scenes.push(i),i):null;for(const e of n)e.text&&(ba(e,1)?(Da(c,e.index-1),a+=1,c={index:r.length+1,paragraphIndex:e.index,startParagraphIndex:e.index,endParagraphIndex:e.index,title:e.text,anchorId:e.chapterAnchorId,wordCount:0,scenes:[]},r.push(c),i=null,d(e,"Scene 1",e.sceneAnchorId),s+=e.wordCount):c&&(t&&La.has(e.text)?(o+=1,d(e)):(c.wordCount+=e.wordCount,i&&(i.wordCount+=e.wordCount),s+=e.wordCount)));return Da(c,n.length-1),{paragraphs:n,chapters:r,usesExplicitScenes:!!t,paragraphCount:n.length,heading1Count:a,heading2Count:o,documentWordCount:s,currentParagraphIndex:null,currentChapter:null,currentScene:null}})(n.items,t),o=Aa(a,r.items);return mn=a,Ta(o),Zn("Cache rebuilt."),a},_a=async()=>{const e=mn?.currentScene;return e&&Number.isInteger(e.startParagraphIndex)&&Number.isInteger(e.endParagraphIndex)&&Gt&&Ft&&window.Word&&"function"==typeof window.Word.run?await window.Word.run(async t=>{const n=t.document.body.paragraphs;n.load("text"),await t.sync();let r=0;const a=Math.min(e.endParagraphIndex,n.items.length-1),o=mn.currentChapter?.startParagraphIndex;for(let t=e.startParagraphIndex;t<=a;t+=1){const e=String(n.items[t]?.text||"").trim();e&&!La.has(e)&&t!==o&&(r+=ka(e))}return e.wordCount=r,lr(mn.currentChapter?.title,e.title,r,mn.currentChapter?.anchorId,e.anchorId,mn.currentChapter?.index),r}):zt},za=async()=>{const e=mn?.currentScene;return e&&Number.isInteger(e.startParagraphIndex)&&Number.isInteger(e.endParagraphIndex)&&Gt&&Ft&&window.Word&&"function"==typeof window.Word.run?await window.Word.run(async t=>{const n=t.document.body.paragraphs;n.load("text"),await t.sync();const r=[],a=Math.min(e.endParagraphIndex,n.items.length-1),o=mn.currentChapter?.startParagraphIndex;for(let t=e.startParagraphIndex;t<=a;t+=1){const e=String(n.items[t]?.text||"").trim();e&&!La.has(e)&&t!==o&&r.push(e)}return r.join("\n")}):""},Ka=async()=>{if(cr(""),!Gt||!Ft||!window.Word||"function"!=typeof window.Word.run)return lr(null,null,null),cr("Word document access is unavailable."),Xr({lastScan:"Failure",lastError:"Word document access is unavailable."}),!1;F&&(F.disabled=!0,F.textContent="Scanning..."),cr("Scanning document structure...");try{const e=await window.Word.run(async e=>{const t=ia();return t?await Ya(e,!!t.usesExplicitScenes):(mn=null,await Ja(e))});return mn||lr(e.currentChapter?.title,e.currentScene?.title,e.currentScene?.wordCount,e.currentChapter?.anchorId,e.currentScene?.anchorId,e.currentChapter?.index),Mr("Not detected"),$a(e),cr(""),Xr({lastScan:"Success",lastError:"-",paragraphs:String(e.paragraphCount),heading1:String(e.heading1Count),heading2:String(e.heading2Count)}),!0}catch(e){const t=Zr(e);return console.error("Unable to scan the Word document.",e),lr(null,null,null),cr(`Unable to scan the Word document: ${t}`),Xr({lastScan:"Failure",lastError:t}),!1}finally{F&&(F.disabled=!1,F.textContent="Refresh Document Structure")}},Qa=async()=>{const e=ia();if(!ca()||!e)return mr("Select a project and book to analyse manuscript structure."),!1;if(!Gt||!Ft||!window.Word||"function"!=typeof window.Word.run)return mr("Word document access is unavailable."),Xr({lastScan:"Failure",lastError:"Word document access is unavailable."}),!1;X&&(X.disabled=!0,X.textContent="Analysing..."),mr("Analysing manuscript structure...");try{const t=await window.Word.run(async e=>await Ja(e)),n=await oo(`/api/word-companion/books/${e.bookId}/structure`);return lr(t.currentChapter?.title,t.currentScene?.title,t.currentScene?.wordCount,t.currentChapter?.anchorId,t.currentScene?.anchorId,t.currentChapter?.index),$a(t),un=((e,t)=>{const n={alreadyLinked:[],couldLink:[],wouldCreateChapters:[],wouldCreateScenes:[],manualReview:[]},r=Array.isArray(t?.chapters)?t.chapters:[];for(const t of Array.isArray(e?.chapters)?e.chapters:[]){const e=Ba(t,r,n);for(const a of Ha(t))Ga(a,e,r,n)}return n})(t,n),Va(un),mr("Preview generated. No changes have been applied."),Xr({lastScan:"Success",lastError:"-",paragraphs:String(t.paragraphCount),heading1:String(t.heading1Count),heading2:String(t.heading2Count)}),!0}catch(e){return console.error("Unable to analyse manuscript structure.",e),mr("Unable to analyse manuscript structure."),Xr({lastScan:"Failure",lastError:Zr(e)}),!1}finally{X&&(X.textContent="Analyse Manuscript Structure",gr())}},Xa=e=>{En&&(En(e),En=null),ut?.close?ut.close():ut&&(ut.hidden=!0)},Za=()=>{const e=((e=un)=>{const t=wr(e);return{linkChapters:t.filter(e=>"couldLink"===e.category&&"Chapter"===e.type).length,linkScenes:t.filter(e=>"couldLink"===e.category&&"Scene"===e.type).length,createChapters:t.filter(e=>"wouldCreateChapters"===e.category).length,createScenes:t.filter(e=>"wouldCreateScenes"===e.category).length,manualReview:Array.isArray(e?.manualReview)?e.manualReview.length:0}})();return(e=>{if(!pt)return;pt.innerHTML="";const t=[`Link ${e.linkChapters+e.linkScenes} chapters/scenes`,`Create ${e.createChapters} chapters`,`Create ${e.createScenes} scenes`],n=document.createElement("ul");for(const e of t){const t=document.createElement("li");t.textContent=e,n.append(t)}pt.append(n)})(e),ut?new Promise(e=>{En=e,ut.showModal?ut.showModal():ut.hidden=!1}):Promise.resolve(window.confirm(`Apply Structure Sync?\n\nThis will:\n\n- Link ${e.linkChapters+e.linkScenes} chapters/scenes\n- Create ${e.createChapters} chapters\n- Create ${e.createScenes} scenes\n\nManual review items will be skipped.`))},eo=(e,t,n="")=>{e.result=t,e.error=n},to=e=>Number.isInteger(e?.wordChapter?.index)&&e.wordChapter.index>0?10*e.wordChapter.index:null,no=e=>Number.isInteger(e?.wordScene?.index)&&e.wordScene.index>0?10*e.wordScene.index:null,ro=async(e,t)=>{const n=await co(`/api/word-companion/books/${e}/chapters`,{title:Gr(t.wordTitle),sortOrder:to(t)});if(!n?.chapterId)throw new Error("Chapter creation did not return a chapter ID.");Pr(),t.pdChapter={chapterId:n.chapterId,title:n.title||t.wordTitle,sortOrder:n.sortOrder||to(t)||0,scenes:[]},t.match=`Chapter ${t.pdChapter.chapterId}: ${t.pdChapter.title}`},ao=async(e,t)=>{const n=t.pdChapter||t.parentItem?.pdChapter;if(!n?.chapterId)throw new Error("Scene parent chapter is not available.");const r=await co(`/api/word-companion/books/${e}/chapters/${n.chapterId}/scenes`,{sceneTitle:Gr(t.wordTitle),sortOrder:no(t)});if(!r?.sceneId)throw new Error("Scene creation did not return a scene ID.");Pr(),t.pdChapter=n,t.pdScene={sceneId:r.sceneId,title:t.wordTitle,sortOrder:no(t)||0},t.match=`Scene ${t.pdScene.sceneId}: ${t.pdScene.title}`},oo=async(e,t={})=>{const n=await window.fetch(e,{credentials:"same-origin",...t,headers:{Accept:"application/json",...t.headers||{}}});if(!n.ok)throw new Error(`Request failed: ${n.status}`);return await n.json()},co=(e,t)=>oo(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)}),io=async(e="")=>{Cn=!1,bn=0,Sn=[],k&&(k.innerHTML=""),pr(C,!0),pa(!1),la(""),pr(v,!0),e&&cr(e);const t=await so();e&&t&&Yt&&cr(e)},so=async()=>{const e=ia();if(!(e&&Gt&&Ft&&window.Word&&"function"==typeof window.Word.run))return!1;cr("Reading manuscript position...");try{Pr(),await Lo(!0),await Jr(e.bookId);const t=await window.Word.run(async t=>await Ya(t,!!e.usesExplicitScenes));return $a(t),Xr({lastScan:"Success",lastError:"-",paragraphs:String(t.paragraphCount),heading1:String(t.heading1Count),heading2:String(t.heading2Count)}),Yt?(_t?await To():await Ao(),br(!1),Cr("Live"),cr(""),!0):(Mr("Not detected"),br(!1),Cr("Live"),cr("Manuscript linked. Click inside a chapter to show the current scene."),!0)}catch(e){return console.error("Unable to initialise bound manuscript runtime.",e),mn=null,Cr("Manual"),cr(`Unable to read manuscript position: ${Zr(e)}`),Xr({lastScan:"Failure",lastError:Zr(e)}),!1}},lo=e=>e?[...e.querySelectorAll("input[type='checkbox']:checked")].map(e=>Number.parseInt(e.value||"",10)).filter(e=>Number.isInteger(e)&&e>0):[],uo=()=>{const e=Number.parseInt(Le?.value||"",10);return Number.isInteger(e)&&e>0?e:null},po=(e,t,n,r)=>{const a=((e,t)=>xa(e).find(e=>va(e.tag,t))||null)(e,r),o=a||e.getRange().insertContentControl();return o.title=t,o.tag=n,o.appearance="Hidden",o},ho=async(e="PlotDirector IDs attached successfully.")=>{if(!Zt||!en)return cr("No resolved PlotDirector scene."),!1;if((Xt&&Xt!==Zt||Qt&&Qt!==en)&&!window.confirm("This scene is already linked. Replace the existing PlotDirector link?"))return!1;if(!Gt||!Ft||!window.Word||"function"!=typeof window.Word.run)return cr("Word document access is unavailable."),!1;se&&(se.disabled=!0,se.textContent="Attaching...");try{return await window.Word.run(async e=>{const t=await Ja(e);if(!t.currentChapter||!t.currentScene)throw new Error("No scene detected in Word. Use Heading 2 for scenes.");const n=t.bodyParagraphs[t.currentChapter.paragraphIndex],r=t.bodyParagraphs[t.currentScene.paragraphIndex];if(!n||!r)throw new Error("Unable to locate the current Word headings.");po(n,"PlotDirector Chapter",`PD-CHAPTER-${en}`,"PD-CHAPTER"),po(r,"PlotDirector Scene",`PD-SCENE-${Zt}`,"PD-SCENE"),await e.sync()}),Qt=en,Xt=Zt,rn=!1,nn="SceneID Anchor",tn="Anchor",cr(e),Xr({lastError:"-"}),dr(),!0}catch(e){return console.error("Unable to attach PlotDirector IDs.",e),cr("Unable to attach PlotDirector IDs."),Xr({lastError:Zr(e)}),dr(),!1}finally{se&&(se.textContent=Xt===Zt?"Attach PlotDirector IDs":"Reattach PlotDirector IDs",dr())}},mo=async e=>{if(!en)return Ar("No resolved PlotDirector chapter."),!1;if(!Gt||!Ft||!window.Word||"function"!=typeof window.Word.run)return Ar("Word document access is unavailable."),!1;try{return await window.Word.run(async e=>{const t=await Ja(e);if(!t.currentChapter)throw new Error("No chapter detected in Word. Use Heading 1 for chapters.");const n=t.bodyParagraphs[t.currentChapter.paragraphIndex];if(!n)throw new Error("Unable to locate the current Word chapter heading.");po(n,"PlotDirector Chapter",`PD-CHAPTER-${en}`,"PD-CHAPTER"),await e.sync()}),Qt=en,rn=!1,nn="ChapterID Anchor",tn="Chapter anchor",Ar(e),cr(e),Xr({lastError:"-"}),dr(),!0}catch(e){return console.error("Unable to attach PlotDirector chapter ID.",e),Ar("Unable to attach PlotDirector chapter ID."),Xr({lastError:Zr(e)}),dr(),!1}},yo=async e=>{jr(),await To(),cr(e),Ar(e)},wo=e=>{ln&&(ln(e),ln=null),ct?.close?ct.close():ct&&(ct.hidden=!0)},fo=()=>{if(!nt)return;const e=Gr(tt?.value||"").toLocaleLowerCase(),t=sn.filter(t=>!e||String(t.title||"").toLocaleLowerCase().includes(e));if(nt.innerHTML="",dn=null,rt&&(rt.disabled=!0),0===t.length){const e=document.createElement("p");return e.className="word-companion-empty-list",e.textContent="No chapters found.",void nt.append(e)}for(const e of t){const t=Number.parseInt(e.chapterId||"",10);if(!Number.isInteger(t)||t<=0)continue;const n=document.createElement("label");n.className="word-companion-scene-option";const r=document.createElement("input");r.type="radio",r.name="word-companion-link-chapter",r.value=String(t),r.addEventListener("change",()=>{dn=t,rt&&(rt.disabled=!1)});const a=document.createElement("span");a.textContent=e.title||"Untitled chapter",n.append(r,a),nt.append(n)}},go=()=>{et?.close?et.close():et&&(et.hidden=!0)},So=async(e,t,n)=>{const r=ia();if(!r)return Dr("Select a PlotDirector book first."),!1;await Kr(r.bookId,e,t,"Manual link","Title Match");return!!await ho(n)&&(Dr(n),Rr(),!0)},Io=e=>{cn&&(cn(e),cn=null),ze?.close?ze.close():ze&&(ze.hidden=!0)},Co=()=>{if(!Ve)return;const e=Gr(Fe?.value||"").toLocaleLowerCase(),t=an.filter(t=>!e||String(t.title||"").toLocaleLowerCase().includes(e));if(Ve.innerHTML="",on=null,Je&&(Je.disabled=!0),0===t.length){const e=document.createElement("p");return e.className="word-companion-empty-list",e.textContent="No scenes found.",void Ve.append(e)}for(const e of t){const t=Number.parseInt(e.sceneId||"",10);if(!Number.isInteger(t)||t<=0)continue;const n=document.createElement("label");n.className="word-companion-scene-option";const r=document.createElement("input");r.type="radio",r.name="word-companion-link-scene",r.value=String(t),r.addEventListener("change",()=>{on=t,Je&&(Je.disabled=!1)});const a=document.createElement("span");a.textContent=e.title||"Untitled scene",n.append(r,a),Ve.append(n)}},bo=()=>{Ge?.close?Ge.close():Ge&&(Ge.hidden=!0)},ko=()=>{Rn=!1,Ir(),Un&&(Un=!1,xo(1e3))},vo=async(e={})=>{const t=e.source||"manual";if(!Zt)return void hr("No resolved PlotDirector scene.");if(!en)return void hr("No resolved PlotDirector chapter.");if(Ln)return void hr("Refresh Current Scene before syncing.");const n=ia(),r=Sa();if(!n||!r)return void hr("Bound manuscript metadata is unavailable.");if(Rn)return Un=!0,void Zn("Scene sync deferred; sync already running.");ur(),Rn=!0,Un=!1;let a=zt;try{a=await _a()}catch(e){return hr("Sync failed"),Xr({lastError:Zr(e)}),Zn("Scene sync failed."),void ko()}if(!Number.isInteger(a)||a<0)return hr("Sync failed"),Zn("Scene sync failed."),void ko();if(Mn===Zt&&On===a)return hr("Synced"),Zn("Sync skipped (count unchanged)."),void ko();Zn("Scene word count changed."),ge&&(ge.disabled=!0,ge.textContent="Syncing..."),hr("Syncing..."),Zn(`Scene sync started (${t}).`);try{const e=await co("/api/word-companion/runtime/scene-word-count",{documentGuid:r,bookId:n.bookId,chapterId:en,sceneId:Zt,wordCount:a}),t=e?.actualWords??a,o=new Date;Mn=Zt,On=t,Qr(Ie,xr(t)),Qr(he,xr(t)),Qr(Ce,Er(o)),Qr(fe,Er(o)),hr("Synced"),Zn("Scene sync succeeded.")}catch(e){hr("Sync failed"),Xr({lastError:Zr(e)}),Zn("Scene sync failed.")}finally{ge&&(ge.textContent="Sync Current Scene"),ko()}},xo=(e=4e3)=>{ur(),Zt&&en&&!Ln&&!Rn&&(Wn=window.setTimeout(()=>{Wn=null,vo({source:"automatic"})},e))},Eo=()=>{Hn&&(window.clearTimeout(Hn),Hn=null)},No=()=>{Fn=null,Vn="",Jn=[],Yn=null,_n="",Eo()},Lo=async(e=!1)=>{const t=ca(),n=Sa();if(!t||!n)return Jn=[],[];if(!e&&Fn===t.projectId&&Vn===n&&Jn.length>0)return Jn;const r=await oo(`/api/word-companion/runtime/characters?projectId=${encodeURIComponent(t.projectId)}&documentGuid=${encodeURIComponent(n)}`);return Fn=t.projectId,Vn=n,Jn=Array.isArray(r?.characters)?r.characters:[],Zn("Character alias cache refreshed."),Jn},Po=(e,t)=>{const n=String(t||"").trim();if(!n)return!1;const r=(a=n,String(a||"").replace(/[.*+?^${}()|[\]\\]/g,"\\$&")).replace(/\s+/g,"\\s+");var a;return new RegExp(`(^|[^\\p{L}\\p{N}_])${r}(?=$|[^\\p{L}\\p{N}_])`,"iu").test(e)},qo=async()=>{if(Hn=null,Zt&&!Ln&&Sa()){if(Bn)return Gn=!0,void Zn("Character suggestion detection deferred; detection already running.");Bn=!0,Gn=!1;try{const[e,t]=await Promise.all([za(),Lo()]),n=((e,t)=>{if(!e||!Array.isArray(t)||0===t.length)return[];const n=new Map;for(const r of t){const t=Number.parseInt(r.characterId||"",10);!Number.isInteger(t)||t<=0||n.has(t)||Po(e,r.matchText)&&n.set(t,r.name||r.matchText||"Character")}return[...n.entries()].map(([e,t])=>({characterId:e,name:t}))})(e,t),r=n.map(e=>e.characterId),a=r.slice().sort((e,t)=>e-t).join(",");if(!a||Yn===Zt&&_n===a)return void Zn("Character suggestions skipped.");const o=await co("/api/word-companion/runtime/character-suggestions",{documentGuid:Sa(),sceneId:Zt,characterIds:r});if(Yn=Zt,_n=a,(o?.createdCount||0)>0){const e=n.slice(0,3).map(e=>e.name).join(", "),t=n.length>3?" +"+(n.length-3):"";cr(e?`Characters detected: ${e}${t}`:o.message)}Zn(o?.message||"Character suggestions submitted.")}catch(e){console.error("Unable to detect character suggestions.",e),Xr({lastError:Zr(e)})}finally{Bn=!1,Gn&&(Gn=!1,Do(1500))}}},Do=(e=2500)=>{Eo(),!Zt||Ln||Bn?Bn&&(Gn=!0):Hn=window.setTimeout(()=>{qo()},e)},Ao=async()=>{const e=ca(),t=ia(),n=Fr(Yt,"chapter");if(Vr({projectId:e?.projectId,projectTitle:e?.title,bookId:t?.bookId,bookTitle:t?oa(t):void 0,detectedChapter:Yt,detectedScene:_t,requestChapter:n,requestScene:"",result:"Not run",chapterId:null,sceneId:null}),!t)return Mr("Not detected"),cr("Select a PlotDirector book first."),!1;if(!Yt)return Mr("Not detected"),cr("No chapter detected in Word. Use Heading 1 for chapters."),!1;Mr("Not detected");try{const e=await Yr(t.bookId),r=Qt?e.find(e=>e.chapterId===Qt):null,a=n.toLocaleLowerCase(),o=a?e.find(e=>Fr(e.title,"chapter").toLocaleLowerCase()===a):null,c=r||o;return c?(jr(),kr(null,c.chapterId,r?"Chapter anchor":"Chapter title"),nn=r?"ChapterID Anchor":"Title Match",ir("Chapter linked to PlotDirector"),cr("No scene detected in Word. Use Heading 2 for scenes."),Vr({result:"Chapter matched",chapterId:c.chapterId,sceneId:null}),!0):(kr(null),ir("Chapter not found in PlotDirector."),cr("Chapter not found in PlotDirector."),Vr({result:"Chapter not matched",chapterId:null,sceneId:null}),Wr("Chapter not found in PlotDirector."),!1)}catch(e){return Mr("Not found in PlotDirector"),Xr({lastError:Zr(e)}),cr("Unable to load PlotDirector chapter data."),!1}},To=async()=>{const e=ca(),t=ia(),n=Fr(Yt,"chapter"),r=Fr(_t,"scene");if(Vr({projectId:e?.projectId,projectTitle:e?.title,bookId:t?.bookId,bookTitle:t?oa(t):void 0,detectedChapter:Yt,detectedScene:_t,requestChapter:n,requestScene:r,result:"Not run",chapterId:null,sceneId:null}),sr({anchorType:Xt?"SceneID Anchor":Qt?"ChapterID Anchor":"Title Match",storedSceneId:Xt,storedChapterId:Qt,resolutionMethod:"-"}),!t)return Mr("Not detected"),cr("Select a PlotDirector book first."),Vr({result:"Error"}),!1;if(!Yt||!_t)return Mr("Not detected"),cr("No scene detected in Word. Use Heading 2 for scenes."),Vr({result:"Error"}),!1;ne&&(ne.disabled=!0,ne.textContent="Refreshing...");const a=()=>{ne&&(ne.disabled=!1,ne.textContent="Refresh PlotDirector Scene")};Mr("Not detected"),cr("Resolving PlotDirector scene...");try{if(Xt){const e=await(async(e,t)=>{const n=await oo(`/api/word-companion/books/${e}/structure`),r=Array.isArray(n?.chapters)?n.chapters:[];for(const e of r){const n=Array.isArray(e.scenes)?e.scenes:[];for(const r of n)if(t(e,r))return{chapter:e,scene:r}}return null})(t.bookId,(e,t)=>t.sceneId===Xt);if(e)return Vr({result:"Matched",chapterId:e.chapter.chapterId,sceneId:e.scene.sceneId}),await Kr(t.bookId,e.scene.sceneId,e.chapter.chapterId,"Anchor","SceneID Anchor"),!0;rn=!0,nn="SceneID Anchor",ir("Not found in PlotDirector"),cr("Stored PlotDirector ID is invalid."),Vr({result:"Error",chapterId:Qt,sceneId:Xt}),sr({anchorType:"SceneID Anchor",storedSceneId:Xt,storedChapterId:Qt,resolutionMethod:"Anchor"})}if(Qt){const e=(await Jr(t.bookId)).find(e=>e.chapterId===Qt),n=e?(Array.isArray(e.scenes)?e.scenes:[]).find(e=>Fr(e.title,"scene").toLocaleLowerCase()===r.toLocaleLowerCase()):null;if(n)return Vr({result:"Matched",chapterId:e.chapterId,sceneId:n.sceneId}),await Kr(t.bookId,n.sceneId,e.chapterId,"Anchor","ChapterID Anchor"),!0;e&&!Xt?(nn="ChapterID Anchor",kr(null,Qt,"Chapter anchor"),Vr({result:"Chapter matched",chapterId:Qt,sceneId:null})):Xt||(nn="ChapterID Anchor",Vr({result:"Chapter anchor not found",chapterId:Qt,sceneId:null}))}const e=await co(`/api/word-companion/books/${t.bookId}/resolve-scene`,{chapterTitle:n,sceneTitle:r});if(!e?.matched||!e.sceneId){const t=rn,n=Number.parseInt(e?.chapterId||"",10),r=Number.isInteger(en)&&en>0?en:null,o=Number.isInteger(n)&&n>0?n:r,c=!!e?.chapterMatched||!!o;return Mr("Not found in PlotDirector"),rn=t,c&&(kr(null,o,o===r?"Chapter anchor":"Chapter title"),ir("Scene not found in PlotDirector.")),cr(t?"Stored PlotDirector ID is invalid.":c?"Scene not found in PlotDirector.":"This chapter does not exist in PlotDirector. Create or link the chapter first."),Vr({result:"Not matched",chapterId:c?o:e?.chapterId,sceneId:e?.sceneId}),t||(c?(jr(),Ur("Scene not found in PlotDirector.")):(Rr(),Wr("Chapter not found in PlotDirector."))),a(),!1}const o=rn;return Vr({result:o?"Matched by title fallback":"Matched",chapterId:e.chapterId,sceneId:e.sceneId}),await Kr(t.bookId,e.sceneId,e.chapterId,o?"Title fallback":"Title","Title Match"),o&&(rn=!0,cr("Stored PlotDirector ID is invalid."),dr()),!0}catch(e){const t=rn;return Xr({lastError:Zr(e)}),Mr("Not found in PlotDirector"),rn=t,cr(t?"Stored PlotDirector ID is invalid.":"Unable to load PlotDirector scene data."),Vr({result:"Error"}),!1}finally{a()}},$o=async()=>{if(Pn=null,jn)return An=!0,void Zn("Runtime update deferred; update already running.");if(!Ot||!ia())return qn=!1,void Zn("Runtime update skipped.");if(!Gt||!Ft||!window.Word||"function"!=typeof window.Word.run)return qn=!1,Cr("Manual"),void cr("Automatic scene tracking is unavailable in this Word version. Use Refresh Current Scene.");if(!mn)return qn=!1,Cr("Manual"),void cr("Document structure is not cached yet. Use Refresh Current Scene.");const e=Date.now()-Dn;if(qn&&eawait(async e=>{const t=e.document.getSelection().paragraphs;return t.load("text,styleBuiltIn,style"),await e.sync(),t.items})(e)),t=Aa(mn,e),n=Ta(t);if(await _a(),!n)return br(!1),Cr("Current scene updated"),xo(),void Do();_t?await To():await Ao(),br(!1),Cr("Current scene updated"),cr("Current scene updated."),xo(),Do()}catch(e){console.error("Unable to refresh current scene from Word selection.",e),Xr({lastError:Zr(e)}),br(!0,"The Word cursor is now in a different scene. Refresh Current Scene before saving.")}finally{jn=!1,(An||qn)&&(An=!1,jo(Tn))}},jo=(e=1200)=>{Pn&&window.clearTimeout(Pn),Pn=window.setTimeout($o,Math.max(0,e)),Cr("Waiting for typing to pause"),Zn("Runtime update scheduled.")},Wo=()=>{((e="selection",t=1200)=>{if(qn=!0,Dn=Date.now(),ur(),Eo(),Zn(`${e} changed.`),jn)return An=!0,void Cr("Waiting for typing to pause");jo(t)})("Selection")},Ro=()=>{if($n&&window.Office?.context?.document&&"function"==typeof window.Office.context.document.removeHandlerAsync&&window.Office?.EventType?.DocumentSelectionChanged)try{window.Office.context.document.removeHandlerAsync(window.Office.EventType.DocumentSelectionChanged,{handler:Wo}),$n=!1}catch(e){console.warn("Unable to remove Word selection tracking handler.",e)}},Uo=async(e,n)=>{if(mn=null,Pr(),!e)return Bt=[],ra(O,"Select a project first"),ra(m,"Select a project first"),or(""),na(t,null),Ia(),Mr("Not detected"),void yr();ra(O,"Loading books..."),or(""),Mr("Not detected"),yr("Select a book to analyse manuscript structure.");try{const r=await oo(`/api/word-companion/projects/${e}/books`);if(Bt=Array.isArray(r.books)?r.books:[],0===Bt.length)return ra(O,"No books available."),ra(m,"No books available."),or("No books available."),na(t,null),Ia(),void ma("No books available.");aa(O,"Choose a book",Bt.map(e=>({...e,displayTitle:oa(e)})),"bookId","displayTitle");const a=Bt.find(e=>e.bookId===n);a&&O?(O.value=String(a.bookId),na(t,a.bookId)):na(t,null),((e=null)=>{if(!m)return;if(0===Bt.length)return void ra(m,"No books available.");aa(m,"Choose a book",Bt.map(e=>({...e,displayTitle:oa(e)})),"bookId","displayTitle");const t=e||Number.parseInt(O?.value||"",10),n=Bt.find(e=>e.bookId===t);n&&(m.value=String(n.bookId)),ua()})(a?.bookId||n),Ia(),Mr((ia(),"Not detected")),yr(ia()?"Ready to analyse manuscript structure.":"Select a book to analyse manuscript structure."),ma(da()?"Ready to scan manuscript structure.":"Select a Book to begin.")}catch{Bt=[],ra(O,"Unable to load books."),ra(m,"Unable to load books."),or("Unable to load books."),na(t,null),Ia(),Mr("Not detected"),yr("Unable to load books."),ma("Unable to load books.")}};for(const e of l)e.addEventListener("click",()=>tr(e.dataset.tabButton));nr(),M?.addEventListener("change",async()=>{const n=Number.parseInt(M.value||"",10);Lr(),h&&Number.isInteger(n)&&n>0&&(h.value=String(n)),na(e,Number.isInteger(n)&&n>0?n:null),na(t,null),Mr("Not detected"),yr(),ma("Select a Book to begin."),await Uo(n,null)}),O?.addEventListener("change",()=>{const e=Number.parseInt(O.value||"",10);Lr(),na(t,Number.isInteger(e)&&e>0?e:null),m&&Number.isInteger(e)&&e>0&&(m.value=String(e)),Ia(),Mr("Not detected"),yr(ia()?"Ready to analyse manuscript structure.":"Select a book to analyse manuscript structure."),ma(da()?"Ready to scan manuscript structure.":"Select a Book to begin.")}),h?.addEventListener("change",async()=>{const n=Number.parseInt(h.value||"",10);Lr(),M&&Number.isInteger(n)&&n>0&&(M.value=String(n)),na(e,Number.isInteger(n)&&n>0?n:null),na(t,null),ma("Select a Book to begin."),await Uo(n,null)}),m?.addEventListener("change",()=>{const e=Number.parseInt(m.value||"",10);Lr(),O&&Number.isInteger(e)&&e>0&&(O.value=String(e)),na(t,Number.isInteger(e)&&e>0?e:null),Ia(),ma(da()?"Ready to scan manuscript structure.":"Select a Book to begin.")}),y?.addEventListener("input",ua),w?.addEventListener("click",async()=>{const e=sa(),t=String(y?.value||"").trim();if(e&&t){w.disabled=!0,la("Creating Book...");try{const n=await co(`/api/word-companion/projects/${e.projectId}/books`,{title:t});y&&(y.value=""),M&&(M.value=String(e.projectId)),await Uo(e.projectId,n.bookId),m&&(m.value=String(n.bookId)),la("Ready to scan manuscript structure.")}catch(e){console.error("Unable to create Book from Word Companion.",e),la(`Unable to create Book: ${Zr(e)}`)}finally{ua()}}else ua()}),f?.addEventListener("click",async()=>{const e=sa(),t=da();if(e&&t)if(Gt&&Ft&&window.Word&&"function"==typeof window.Word.run){f&&(f.disabled=!0,f.textContent="Scanning..."),la("Scanning manuscript structure...");try{const n=await window.Word.run(async e=>{const n=e.document.body.paragraphs;return n.load("text,styleBuiltIn,style"),await e.sync(),((e,t)=>{const n=[];let r=null,a=null,o=0;const c=[],i=new Set(["***","###"]),s=()=>{if(!r)return null;const e={title:`Scene ${r.scenes.length+1}`,sortOrder:10*(r.scenes.length+1),wordCount:0};return r.scenes.push(e),e};return e.forEach(e=>{const d=String(e.text||"").trim();if(!d)return;if(c.push(d),ba(e,1))return r={title:d,sortOrder:10*(n.length+1),wordCount:0,scenes:[]},n.push(r),a=s(),void(o+=ka(d));if(!r||!a)return;if(t&&i.has(d))return void(a=s());const l=ka(d);r.wordCount+=l,a.wordCount+=l,o+=l}),{chapters:n,chapterCount:n.length,sceneCount:n.reduce((e,t)=>e+t.scenes.length,0),wordCount:o,documentText:c.join("\n")}})(n.items,!!t.usesExplicitScenes)});gn=n,In=!1;const r=await co("/api/word-companion/manuscript/analyse",{projectId:e.projectId,bookId:t.bookId,documentGuid:ga(),chapterCount:n.chapterCount,sceneCount:n.sceneCount,wordCount:n.wordCount});fn=r,(e=>{if(!I)return;I.innerHTML="";const t=document.createElement("strong");t.textContent="Manuscript Analysis",I.append(t);const n=document.createElement("dl"),r=[["Project",e.projectTitle],["Book",oa({title:e.bookTitle,subtitle:e.bookSubtitle})],["Chapters",Number(e.chapterCount||0).toLocaleString()],["Scenes",Number(e.sceneCount||0).toLocaleString()],["Words",Number(e.wordCount||0).toLocaleString()]];for(const[e,t]of r){const r=document.createElement("dt");r.textContent=e;const a=document.createElement("dd");a.textContent=t||"-",n.append(r,a)}I.append(n),pr(I,!1),pr(L,!1),la(e.message||"Preview generated."),ua()})(r);try{const t=await co("/api/word-companion/manuscript/discover-characters",{projectId:e.projectId,documentText:n.documentText||""});Sn=Array.isArray(t?.candidates)?t.candidates:[],pr(C,!0),pr(v,!0)}catch(e){console.error("Unable to discover character candidates.",e),Sn=[],pr(C,!0),pr(v,!0)}Xr({lastScan:"Success",lastError:"-",paragraphs:"-",heading1:String(n.chapterCount),heading2:"-"})}catch(e){console.error("Unable to scan manuscript for first-run import.",e),ma(`Unable to scan manuscript: ${Zr(e)}`),Xr({lastScan:"Failure",lastError:Zr(e)})}finally{f&&(f.textContent="Scan Manuscript"),ua()}}else ma("Word document access is unavailable.");else ma("Select a Project and Book to begin.")}),P?.addEventListener("click",async()=>{const n=sa(),i=da();if(!(n&&i&&gn&&fn?.canImport))return void ua();let s=!1;if(!fn.requiresReplaceConfirmation||(s=await new Promise(e=>{if(!D||"function"!=typeof D.showModal)return void e(window.confirm("This Book already contains planned chapters and scenes.\n\nImporting this manuscript will replace the planned structure.\n\nContinue?"));const t=t=>{A?.removeEventListener("click",n),T?.removeEventListener("click",r),D?.removeEventListener("cancel",a),D?.close(),e(t)},n=()=>t(!0),r=()=>t(!1),a=e=>{e.preventDefault(),t(!1)};A?.addEventListener("click",n),T?.addEventListener("click",r),D?.addEventListener("cancel",a),D.showModal()}),s)){kn=!0,ua(),la("Importing manuscript structure...");try{const l=ga(),u=await co("/api/word-companion/manuscript/import",{projectId:n.projectId,bookId:i.bookId,documentGuid:l,bindingVersion:1,replacePlanned:s,chapters:gn.chapters});if(!u.imported)return fn={...fn,canImport:!u.requiresReplaceConfirmation,requiresReplaceConfirmation:!!u.requiresReplaceConfirmation,message:u.message||fn.message},la(u.message||"Import was not completed."),void ua();const p=u.manuscriptDocument;await(d={documentGuid:p?.documentGuid||l,bookId:u.bookId,projectId:u.projectId,bindingVersion:p?.bindingVersion||1},new Promise((e,t)=>{const n=window.Office?.context?.document?.settings;n?(n.set(r,d.documentGuid),n.set(a,String(d.bookId)),n.set(o,String(d.projectId)),n.set(c,String(d.bindingVersion||1)),n.saveAsync(n=>{n.status===window.Office.AsyncResultStatus.Succeeded?e():t(n.error||new Error("Unable to save Word document metadata."))})):t(new Error("Word document settings are unavailable."))})),pn={documentGuid:p?.documentGuid||l,bookId:u.bookId,projectId:u.projectId,bindingVersion:p?.bindingVersion||1},na(e,u.projectId),na(t,u.bookId),M&&(M.value=String(u.projectId));const h=Sn;await Uo(u.projectId,u.bookId),rr("Connected"),In=!0,Cn=h.length>0,bn=Cn?Date.now():0,Sn=h,h.length>0?(pa(!0),wa(h),pr(L,!0),pr(v,!1),la(u.message||"Manuscript structure imported."),cr(u.message||"Manuscript structure imported."),window.setTimeout(ua,750)):await io(u.message||"Manuscript structure imported.")}catch(e){console.error("Unable to import manuscript structure.",e),la(`Unable to import manuscript: ${Zr(e)}`)}finally{kn=!1,ua()}var d}else la("Import cancelled.")}),x?.addEventListener("click",async()=>{const e=sa()||ca(),t=ya();if(!Cn||Date.now()-bn<750||!e||0===t.length)ua();else{vn=!0,ua(),Qr(b,"Creating selected characters...");try{const n=await co("/api/word-companion/manuscript/create-discovered-characters",{projectId:e.projectId,candidateNames:t});cr(n.message||"Characters created."),Qr(b,`${n.createdCount||0} created, ${n.skippedCount||0} already existed.`),await io(n.message||"Characters created.")}catch(e){console.error("Unable to create discovered characters.",e),Qr(b,`Unable to create characters: ${Zr(e)}`)}finally{vn=!1,ua()}}}),E?.addEventListener("click",()=>io("Character creation skipped.")),N?.addEventListener("click",()=>io()),g?.addEventListener("click",()=>pa(!1)),q?.addEventListener("click",()=>ma("Import cancelled.")),F?.addEventListener("click",Ka),X?.addEventListener("click",Qa),Z?.addEventListener("click",async()=>{const e=ia();if(!e||0===wr().length||xn)return void fr();if(!await Za())return;xn=!0,gr(),mr("Applying structure sync...");const t={createdChapters:0,createdScenes:0,linkedChapters:0,linkedScenes:0,skipped:Array.isArray(un?.manualReview)?un.manualReview.length:0,failed:0},n=wr().filter(e=>"couldLink"===e.category&&"Chapter"===e.type),r=wr().filter(e=>"wouldCreateChapters"===e.category),a=wr().filter(e=>"couldLink"===e.category&&"Scene"===e.type),o=wr().filter(e=>"wouldCreateScenes"===e.category),c=[];let i="";const s=(e,t)=>{c.push({item:e,counterName:t})},d=async(e,n)=>{try{await(async e=>{if(!Gt||!Ft||!window.Word||"function"!=typeof window.Word.run)throw new Error("Word document access is unavailable.");await window.Word.run(async t=>{const n=await Ja(t),r="Chapter"===e.type?e.wordChapter:e.wordScene,a=Number.isInteger(r?.paragraphIndex)?n.bodyParagraphs[r.paragraphIndex]:null;if(!a)throw new Error("Unable to locate the Word heading.");if("Chapter"===e.type){const t=e.pdChapter?.chapterId;if(!t)throw new Error("Chapter ID is not available.");po(a,"PlotDirector Chapter",`PD-CHAPTER-${t}`,"PD-CHAPTER")}else{const t=e.pdScene?.sceneId;if(!t)throw new Error("Scene ID is not available.");po(a,"PlotDirector Scene",`PD-SCENE-${t}`,"PD-SCENE")}await t.sync()})})(e),eo(e,"Success"),t[n]+=1}catch(n){eo(e,"Failed",Zr(n)),t.failed+=1}};try{for(const e of n)s(e,"linkedChapters");for(const n of r)try{await ro(e.bookId,n),s(n,"createdChapters")}catch(e){eo(n,"Failed",Zr(e)),t.failed+=1}for(const e of a)s(e,"linkedScenes");for(const n of o)try{await ao(e.bookId,n),s(n,"createdScenes")}catch(e){eo(n,"Failed",Zr(e)),t.failed+=1}for(const e of c)await d(e.item,e.counterName);for(const e of un.manualReview||[])eo(e,"Skipped");Va(un),i=(e=>`Structure Sync Complete. Created: ${e.createdChapters} Chapters, ${e.createdScenes} Scenes. Linked: ${e.linkedChapters} Chapters, ${e.linkedScenes} Scenes. Skipped: ${e.skipped} Manual Review items. Failed: ${e.failed} Items.`)(t),mr(i)}finally{xn=!1,gr(),i&&(Pr(),await Qa(),mr(`${i} Preview refreshed.`))}}),ht?.addEventListener("click",()=>Xa(!0)),mt?.addEventListener("click",()=>Xa(!1)),ut?.addEventListener("cancel",e=>{e.preventDefault(),Xa(!1)}),ne?.addEventListener("click",To),G?.addEventListener("click",async()=>{if(!ia())return cr("Select a PlotDirector book first."),void Mr("Not detected");Pn&&(window.clearTimeout(Pn),Pn=null),qn=!1,An=!1,vr(!0),Cr("Updating...");try{await Lo(!0);if(!await Ka())return;if(br(!1),!_t)return await Ao(),void Cr("Current scene updated");await To(),Cr("Current scene updated")}finally{vr(!1)}}),ge?.addEventListener("click",()=>vo({source:"manual"})),Pe?.addEventListener("click",async()=>{if(Zt)if(!Ln&&await(async()=>{if(!Zt)return!1;if(!Gt||!Ft||!window.Word||"function"!=typeof window.Word.run)return br(!0,"The Word cursor is now in a different scene. Refresh Current Scene before saving."),!1;try{const e=await window.Word.run(async e=>await Ja(e)),t=e.currentChapter?.title||"",n=e.currentScene?.title||"",r=e.currentScene?.anchorId||null,a=e.currentChapter?.anchorId||null,o=Number.isInteger(r)&&r===Zt,c=Number.isInteger(a)&&a===en,i=Fr(n,"scene").toLocaleLowerCase()===Fr(zn||_t,"scene").toLocaleLowerCase(),s=Fr(t,"chapter").toLocaleLowerCase()===Fr(Kn||Yt,"chapter").toLocaleLowerCase();return o||i&&(c||s)?(br(!1),!0):(br(!0,"The Word cursor is now in a different scene. Refresh Current Scene before saving."),!1)}catch(e){return console.error("Unable to verify current Word scene before saving.",e),Xr({lastError:Zr(e)}),br(!0,"The Word cursor is now in a different scene. Refresh Current Scene before saving."),!1}})()){Pe&&(Pe.disabled=!0,Pe.textContent="Saving...");try{await(e=`/api/word-companion/scenes/${Zt}/links`,t={characterIds:lo(Ee),assetIds:lo(Ne),locationIds:[],primaryLocationId:uo()},oo(e,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})),(()=>{const e=new Set(lo(Ee)),t=new Set(lo(Ne));Xn={characters:Xn.characters.map(t=>({...t,linked:e.has(Number.parseInt(Or(t,"character"),10))})),assets:Xn.assets.map(e=>({...e,linked:t.has(Number.parseInt(Or(e,"asset"),10))})),locations:Xn.locations,primaryLocationId:uo()}})(),qr("Scene links saved successfully."),Xr({lastError:"-"})}catch(e){qr("Unable to save scene links."),Xr({lastError:Zr(e)})}finally{Pe&&(Pe.disabled=!Zt||Ln,Pe.textContent="Save Scene Links")}var e,t}else qr("The Word cursor is now in a different scene. Refresh Current Scene before saving.");else qr("Link a PlotDirector scene first.")}),se?.addEventListener("click",async()=>{await ho()}),$e?.addEventListener("click",async()=>{const e=ia();if(!e||!Yt||en)return void Wr("Chapter not found in PlotDirector.");const t=Gr(Yt),n=await((e,t)=>(Qr(it,`"${e}"`),Qr(st,`"${t}"`),ct?new Promise(e=>{ln=e,ct.showModal?ct.showModal():ct.hidden=!1}):Promise.resolve(window.confirm(`Create PlotDirector chapter:\n\n"${e}"\n\nin book:\n\n"${t}"\n\n?`))))(t,oa(e)||"selected book");if(n){$e&&($e.disabled=!0,$e.textContent="Creating...");try{const n=Number.isInteger(Kt)&&Kt>0?10*Kt:null,r=await co(`/api/word-companion/books/${e.bookId}/chapters`,{title:t,sortOrder:n});if(!r?.chapterId)throw new Error("Chapter creation did not return a chapter ID.");Pr(),kr(null,r.chapterId,"Manual chapter link");if(!await mo("Chapter created and linked successfully."))return;await yo("Chapter created and linked successfully.")}catch(e){Ar("Unable to create chapter."),Xr({lastError:Zr(e)})}finally{$e&&($e.disabled=!Tr(),$e.textContent="Create Chapter in PlotDirector")}}}),je?.addEventListener("click",async()=>{const e=ia();if(e&&Yt&&!en){je&&(je.disabled=!0,je.textContent="Loading...");try{sn=await Yr(e.bookId),dn=null,tt&&(tt.value=""),Qr(ot,""),fo(),et?.showModal?et.showModal():et&&(et.hidden=!1)}catch(e){Ar("Unable to load chapters."),Xr({lastError:Zr(e)})}finally{je&&(je.disabled=!Tr(),je.textContent="Link to Existing Chapter")}}else Wr("Chapter not found in PlotDirector.")}),tt?.addEventListener("input",fo),rt?.addEventListener("click",async()=>{const e=sn.find(e=>e.chapterId===dn);if(e){rt&&(rt.disabled=!0,rt.textContent="Linking...");try{kr(null,e.chapterId,"Manual chapter link");if(!await mo("Chapter linked successfully."))return;go(),await yo("Chapter linked successfully.")}catch(e){Qr(ot,"Unable to link chapter."),Ar("Unable to link chapter."),Xr({lastError:Zr(e)})}finally{rt&&(rt.disabled=!dn,rt.textContent="Link Chapter")}}else Qr(ot,"Select a chapter.")}),at?.addEventListener("click",go),dt?.addEventListener("click",()=>wo(!0)),lt?.addEventListener("click",()=>wo(!1)),ct?.addEventListener("cancel",e=>{e.preventDefault(),wo(!1)}),Oe?.addEventListener("click",async()=>{const e=ia();if(!e||!_t)return void Ur("Scene not found in PlotDirector.");const t=Fr(_t,"scene"),n=Fr(Yt,"chapter"),r=await((e,t)=>(Qr(Ke,`"${e}"`),Qr(Qe,`"${t}"`),ze?new Promise(e=>{cn=e,ze.showModal?ze.showModal():ze.hidden=!1}):Promise.resolve(window.confirm(`Create PlotDirector scene:\n\n"${e}"\n\nwithin chapter:\n\n"${t}"\n\n?`))))(t,n);if(r){Oe&&(Oe.disabled=!0,Oe.textContent="Creating...");try{const n=await zr();if(!n)return void Ur("This chapter does not exist in PlotDirector. Create or link the chapter first.");const r=await co(`/api/word-companion/books/${e.bookId}/chapters/${n.chapterId}/scenes`,{sceneTitle:t});if(!r?.sceneId||!r?.chapterId)throw new Error("Scene creation did not return a scene ID.");Pr(),await So(r.sceneId,r.chapterId,"Scene created and linked successfully.")}catch(e){Dr("Unable to create scene."),Xr({lastError:Zr(e)})}finally{Oe&&(Oe.disabled=!$r(),Oe.textContent="Create Scene in PlotDirector")}}}),He?.addEventListener("click",async()=>{const e=ia();if(e&&_t){He&&(He.disabled=!0,He.textContent="Loading...");try{const t=await Jr(e.bookId),n=_r(t);if(!n)return void Ur("This chapter does not exist in PlotDirector. Create or link the chapter first.");an=Array.isArray(n.scenes)?n.scenes:[],on=null,Fe&&(Fe.value=""),Qr(_e,""),Co(),Ge?.showModal?Ge.showModal():Ge&&(Ge.hidden=!1)}catch(e){Dr("Unable to load scenes."),Xr({lastError:Zr(e)})}finally{He&&(He.disabled=!$r(),He.textContent="Link to Existing Scene")}}else Ur("Scene not found in PlotDirector.")}),Fe?.addEventListener("input",Co),Je?.addEventListener("click",async()=>{const e=ia(),t=an.find(e=>e.sceneId===on);if(e&&t){Je&&(Je.disabled=!0,Je.textContent="Linking...");try{const e=await zr();if(!e)throw new Error("This chapter does not exist in PlotDirector. Create or link the chapter first.");bo(),await So(t.sceneId,e.chapterId,"Scene linked successfully.")}catch(e){Qr(_e,"Unable to link scene."),Dr("Unable to link scene."),Xr({lastError:Zr(e)})}finally{Je&&(Je.disabled=!on,Je.textContent="Link Scene")}}else Qr(_e,"Select a scene.")}),Ye?.addEventListener("click",bo),Xe?.addEventListener("click",()=>Io(!0)),Ze?.addEventListener("click",()=>Io(!1)),ze?.addEventListener("cancel",e=>{e.preventDefault(),Io(!1)}),Et?.addEventListener("click",async()=>{Et&&(Et.disabled=!0,Et.textContent="Running...");try{if(await ea(),!Gt||!Ft||!window.Word||"function"!=typeof window.Word.run)return void Xr({lastScan:"Failure",lastError:"Word document access is unavailable.",paragraphs:"-",heading1:"-",heading2:"-"});const e=await window.Word.run(async e=>{const t=e.document.body.paragraphs;return t.load("items"),await e.sync(),t.items.length});Xr({lastScan:"Success",lastError:"-",paragraphs:String(e)})}catch(e){console.error("Word Companion diagnostics failed.",e);const t=Zr(e);Xr({lastScan:"Failure",lastError:t}),cr(`Unable to scan the Word document: ${t}`)}finally{Et&&(Et.disabled=!1,Et.textContent="Run Diagnostics")}});const Mo=Ot?(async()=>{ra(M,"Loading projects..."),ra(O,"Select a project first"),ra(h,"Loading projects..."),ra(m,"Select a project first"),ar(""),or("");try{const n=await oo("/api/word-companion/projects");if(Ht=Array.isArray(n.projects)?n.projects:[],0===Ht.length)return ra(M,"No projects available."),ra(h,"No projects available."),ar("No projects available."),na(e,null),na(t,null),Ia(),void ma("No projects available.");aa(M,"Choose a project",Ht,"projectId","title"),ha();const r=ta(e),a=Ht.find(e=>e.projectId===r);a&&M?(M.value=String(a.projectId),h&&(h.value=String(a.projectId)),na(e,a.projectId),await Uo(a.projectId,ta(t))):(na(e,null),na(t,null),Ia(),ma("Select a Project and Book to begin."))}catch{Ht=[],Bt=[],ra(M,"Unable to connect to PlotDirector."),ra(O,"Select a project first"),ra(h,"Unable to connect to PlotDirector."),ra(m,"Select a project first"),rr("Unable to connect to PlotDirector."),ar("Unable to connect to PlotDirector."),na(e,null),na(t,null),Ia(),ma("Unable to connect to PlotDirector.")}})():Promise.resolve();if(Ot||(ra(M,"Please sign in to PlotDirector."),ra(O,"Please sign in to PlotDirector."),ra(h,"Please sign in to PlotDirector."),ra(m,"Please sign in to PlotDirector."),Ia()),!window.Office||"function"!=typeof window.Office.onReady)return er("Word Companion ready"),cr("Word document access is unavailable."),Cr("Manual"),void Xr({host:"Unavailable",platform:"Unavailable",ready:"No",wordApi:"No"});ea().then(async()=>{er("Word Companion ready"),await Mo,await(async()=>{if(!Ot||!Ft)return void pa(!1);const n=fa();if(n)try{const r=await oo(`/api/word-companion/runtime/book/${n.bookId}?documentGuid=${encodeURIComponent(n.documentGuid)}`),a=r?.manuscriptDocument;if(r?.bookId===n.bookId&&r?.projectId===n.projectId&&a&&String(a.documentGuid).toLowerCase()===n.documentGuid.toLowerCase())return pn=n,Nr(r),na(e,r.projectId),na(t,r.bookId),M&&(M.value=String(r.projectId)),await Uo(r.projectId,r.bookId),pa(!1),rr("Connected"),or("Bound manuscript detected."),void await so()}catch{}pn=null,Lr(),ha(),sa()?await Uo(sa().projectId,null):ra(m,"Select a project first"),ma("Select a Project and Book to begin."),pa(!0)})(),Ft?(()=>{if(Ot){if(!window.Office?.context?.document||"function"!=typeof window.Office.context.document.addHandlerAsync||!window.Office?.EventType?.DocumentSelectionChanged)return Cr("Manual"),void cr("Automatic scene tracking is unavailable in this Word version. Use Refresh Current Scene.");try{window.Office.context.document.addHandlerAsync(window.Office.EventType.DocumentSelectionChanged,Wo,e=>{e?.status===window.Office.AsyncResultStatus.Succeeded?($n=!0,Cr("Live")):(Cr("Manual"),cr("Automatic scene tracking is unavailable in this Word version. Use Refresh Current Scene."))}),window.addEventListener("beforeunload",Ro)}catch(e){console.warn("Unable to register Word selection tracking handler.",e),Cr("Manual"),cr("Automatic scene tracking is unavailable in this Word version. Use Refresh Current Scene.")}}})():(cr("Word document access is unavailable."),Cr("Manual"))}).catch(e=>{console.error("Office readiness check failed.",e),rr("Unable to connect to PlotDirector."),er("Word Companion unavailable"),cr("Word document access is unavailable."),Xr({ready:"No",wordApi:"No",lastScan:"Failure"})})})(); \ No newline at end of file +(()=>{const e="plotdirector.word.projectId",t="plotdirector.word.bookId",n="plotdirector.word.activeTab",r="plotdirector.word.documentGuid",a="plotdirector.word.boundBookId",o="plotdirector.word.boundProjectId",c="plotdirector.word.bindingVersion",i=new Set(["scene","links","structure","diagnostics"]),s=document.querySelector(".word-companion-shell"),d=document.querySelector(".word-companion-tabs"),l=[...document.querySelectorAll("[data-tab-button]")],u=[...document.querySelectorAll("[data-tab-panel]")],p=document.querySelector("[data-first-run-wizard]"),h=document.querySelector("[data-first-run-project-select]"),m=document.querySelector("[data-first-run-book-select]"),y=document.querySelector("[data-first-run-new-book-title]"),w=document.querySelector("[data-first-run-create-book]"),f=document.querySelector("[data-first-run-scan]"),g=document.querySelector("[data-first-run-cancel]"),S=document.querySelector("[data-first-run-status]"),I=document.querySelector("[data-first-run-summary]"),C=document.querySelector("[data-first-run-character-section]"),b=document.querySelector("[data-first-run-character-status]"),k=document.querySelector("[data-first-run-character-candidates]"),v=document.querySelector("[data-first-run-character-actions]"),x=document.querySelector("[data-first-run-create-characters]"),E=document.querySelector("[data-first-run-skip-characters]"),N=document.querySelector("[data-first-run-continue]"),L=document.querySelector("[data-first-run-import-actions]"),P=document.querySelector("[data-first-run-import]"),q=document.querySelector("[data-first-run-import-cancel]"),D=document.querySelector("[data-first-run-replace-dialog]"),A=document.querySelector("[data-first-run-replace-confirm]"),$=document.querySelector("[data-first-run-replace-cancel]"),T=document.querySelector("[data-office-status]"),j=document.querySelector("[data-connection-status]"),W=document.querySelector("[data-summary-connection]"),R=document.querySelector("[data-summary-project]"),U=document.querySelector("[data-summary-book]"),M=document.querySelector("[data-project-select]"),O=document.querySelector("[data-book-select]"),H=document.querySelector("[data-project-message]"),B=document.querySelector("[data-book-message]"),G=document.querySelector("[data-refresh-current-scene]"),F=document.querySelector("[data-refresh-document]"),V=document.querySelector("[data-current-chapter]"),J=document.querySelector("[data-current-scene]"),Y=document.querySelector("[data-current-word-count]"),_=document.querySelector("[data-scene-tracking-status]"),z=document.querySelector("[data-document-message]"),K=document.querySelector("[data-sync-note]"),Q=document.querySelector("[data-document-outline]"),X=document.querySelector("[data-analyse-manuscript-structure]"),Z=document.querySelector("[data-apply-structure-sync]"),ee=document.querySelector("[data-structure-preview-status]"),te=document.querySelector("[data-structure-preview-results]"),ne=document.querySelector("[data-refresh-plotdirector-scene]"),re=document.querySelector("[data-plotdirector-scene-status]"),ae=document.querySelector("[data-anchor-status]"),oe=document.querySelector("[data-anchor-book-id]"),ce=document.querySelector("[data-anchor-chapter-id]"),ie=document.querySelector("[data-anchor-scene-id]"),se=document.querySelector("[data-attach-plotdirector-ids]"),de=document.querySelector("[data-plotdirector-scene-details]"),le=document.querySelector("[data-plotdirector-scene-title]"),ue=document.querySelector("[data-plotdirector-revision-status]"),pe=document.querySelector("[data-plotdirector-estimated-words]"),he=document.querySelector("[data-plotdirector-actual-words]"),me=document.querySelector("[data-plotdirector-blocked-status]"),ye=document.querySelector("[data-plotdirector-blocked-reason-row]"),we=document.querySelector("[data-plotdirector-blocked-reason]"),fe=document.querySelector("[data-runtime-last-sync]"),ge=document.querySelector("[data-sync-scene-progress]"),Se=document.querySelector("[data-sync-word-count]"),Ie=document.querySelector("[data-sync-plotdirector-count]"),Ce=document.querySelector("[data-sync-last-synced]"),be=document.querySelector("[data-sync-status]"),ke=document.querySelector("[data-writing-brief-block]"),ve=document.querySelector("[data-writing-brief]"),xe=document.querySelector("[data-plotdirector-link-groups]"),Ee=document.querySelector("[data-character-chips]"),Ne=document.querySelector("[data-asset-chips]"),Le=(document.querySelector("[data-location-chips]"),document.querySelector("[data-primary-location-select]")),Pe=document.querySelector("[data-save-scene-links]"),qe=document.querySelector("[data-scene-links-status]"),De=document.querySelector("[data-links-editing-scene]"),Ae=document.querySelector("[data-chapter-create-link]"),$e=document.querySelector("[data-chapter-create-link-chapter]"),Te=document.querySelector("[data-create-plotdirector-chapter]"),je=document.querySelector("[data-link-existing-chapter]"),We=document.querySelector("[data-chapter-create-link-status]"),Re=document.querySelector("[data-scene-create-link]"),Ue=document.querySelector("[data-create-link-chapter]"),Me=document.querySelector("[data-create-link-scene]"),Oe=document.querySelector("[data-create-plotdirector-scene]"),He=document.querySelector("[data-link-existing-scene]"),Be=document.querySelector("[data-create-link-status]"),Ge=document.querySelector("[data-link-existing-dialog]"),Fe=document.querySelector("[data-link-scene-search]"),Ve=document.querySelector("[data-link-scene-options]"),Je=document.querySelector("[data-link-selected-scene]"),Ye=document.querySelector("[data-link-dialog-cancel]"),_e=document.querySelector("[data-link-dialog-status]"),ze=document.querySelector("[data-create-scene-dialog]"),Ke=document.querySelector("[data-create-dialog-scene]"),Qe=document.querySelector("[data-create-dialog-chapter]"),Xe=document.querySelector("[data-create-dialog-confirm]"),Ze=document.querySelector("[data-create-dialog-cancel]"),et=document.querySelector("[data-link-existing-chapter-dialog]"),tt=document.querySelector("[data-link-chapter-search]"),nt=document.querySelector("[data-link-chapter-options]"),rt=document.querySelector("[data-link-selected-chapter]"),at=document.querySelector("[data-link-chapter-dialog-cancel]"),ot=document.querySelector("[data-link-chapter-dialog-status]"),ct=document.querySelector("[data-create-chapter-dialog]"),it=document.querySelector("[data-create-chapter-dialog-chapter]"),st=document.querySelector("[data-create-chapter-dialog-book]"),dt=document.querySelector("[data-create-chapter-dialog-confirm]"),lt=document.querySelector("[data-create-chapter-dialog-cancel]"),ut=document.querySelector("[data-apply-structure-sync-dialog]"),pt=document.querySelector("[data-apply-structure-sync-summary]"),ht=document.querySelector("[data-apply-structure-sync-confirm]"),mt=document.querySelector("[data-apply-structure-sync-cancel]"),yt=document.querySelector("[data-resolve-project-id]"),wt=document.querySelector("[data-resolve-project-title]"),ft=document.querySelector("[data-resolve-book-id]"),gt=document.querySelector("[data-resolve-book-title]"),St=document.querySelector("[data-resolve-detected-chapter]"),It=document.querySelector("[data-resolve-detected-scene]"),Ct=document.querySelector("[data-resolve-request-chapter]"),bt=document.querySelector("[data-resolve-request-scene]"),kt=document.querySelector("[data-resolve-result]"),vt=document.querySelector("[data-resolve-chapter-id]"),xt=document.querySelector("[data-resolve-scene-id]"),Et=document.querySelector("[data-run-diagnostics]"),Nt=document.querySelector("[data-diagnostic-host]"),Lt=document.querySelector("[data-diagnostic-platform]"),Pt=document.querySelector("[data-diagnostic-ready]"),qt=document.querySelector("[data-diagnostic-word-api]"),Dt=document.querySelector("[data-diagnostic-last-scan]"),At=document.querySelector("[data-diagnostic-last-error]"),$t=document.querySelector("[data-diagnostic-anchor-type]"),Tt=document.querySelector("[data-diagnostic-stored-scene-id]"),jt=document.querySelector("[data-diagnostic-stored-chapter-id]"),Wt=document.querySelector("[data-diagnostic-resolution-method]"),Rt=document.querySelector("[data-diagnostic-paragraphs]"),Ut=document.querySelector("[data-diagnostic-heading1]"),Mt=document.querySelector("[data-diagnostic-heading2]"),Ot="true"===s?.dataset.authenticated;let Ht=[],Bt=[],Gt=!1,Ft=!1,Vt="Unknown",Jt="Unknown",Yt="",_t="",zt=null,Kt=null,Qt=null,Xt=null,Zt=null,en=null,tn="",nn="Title Match",rn=!1,an=[],on=null,cn=null,sn=[],dn=null,ln=null,un=null,pn=null,hn=null,mn=null,yn=null,wn=null,fn=null,gn=null,Sn=[],In=!1,Cn=!1,bn=0,kn=!1,vn=!1,xn=!1,En=null,Nn="Manual",Ln=!1,Pn=null,qn=!1,Dn=0,An=!1;const $n=1200;let Tn=!1,jn=!1,Wn=null,Rn=!1,Un=!1,Mn=null,On=null,Hn=null,Bn=!1,Gn=!1,Fn=null,Vn="",Jn=[],Yn=null,_n="",zn="",Kn="",Qn="",Xn=0,Zn={characters:[],assets:[],locations:[],primaryLocationId:null};const er=e=>{const t=Date.now();t-Xn<1e3||(Xn=t,console.debug(`[Word Companion Runtime] ${e}`))},tr=e=>{T&&(T.textContent=e)},nr=(e,t=!0)=>{const r=i.has(e)&&l.some(t=>t.dataset.tabButton===e)?e:"scene";for(const e of l){const t=e.dataset.tabButton===r;e.classList.toggle("is-active",t),e.setAttribute("aria-selected",t?"true":"false")}for(const e of u){const t=e.dataset.tabPanel===r;e.classList.toggle("is-active",t),e.hidden=!t}t&&((e,t)=>{try{t?window.localStorage.setItem(e,String(t)):window.localStorage.removeItem(e)}catch{}})(n,r)},rr=()=>{const e=(e=>{try{return window.localStorage.getItem(e)||""}catch{return""}})(n);nr(i.has(e)?e:"scene",!1)},ar=e=>{j&&(j.textContent=e),W&&(W.textContent=e)},or=e=>{H&&(H.textContent=e)},cr=e=>{B&&(B.textContent=e)},ir=e=>{z&&(z.textContent=e)},sr=e=>{re&&(re.textContent=e)},dr=e=>{const t=t=>Object.prototype.hasOwnProperty.call(e,t);t("anchorType")&&Xr($t,Er(e.anchorType)),t("storedSceneId")&&Xr(Tt,Er(e.storedSceneId)),t("storedChapterId")&&Xr(jt,Er(e.storedChapterId)),t("resolutionMethod")&&Xr(Wt,Er(e.resolutionMethod))},lr=()=>{const e=sa(),t=Number.isInteger(Zt)&&Zt>0&&Xt===Zt,n=!Number.isInteger(en)||en<=0||Qt===en,r=t&&n;Xr(ae,r?"Attached to PlotDirector":"Not attached"),Xr(oe,e?.bookId?String(e.bookId):"-"),Xr(ce,Number.isInteger(en)&&en>0?String(en):"-"),Xr(ie,Number.isInteger(Zt)&&Zt>0?String(Zt):"-"),se&&(se.disabled=!Zt||r&&!rn,se.textContent=Xt&&!r?"Reattach PlotDirector IDs":"Attach PlotDirector IDs"),dr({anchorType:nn||"Title Match",storedSceneId:Xt,storedChapterId:Qt,resolutionMethod:tn})},ur=(e,t,n,r=null,a=null,o=null)=>{const c=e||"",i=t||"",s=Number.isInteger(n)?n:null,d=Number.isInteger(o)&&o>0?o:null,l=Number.isInteger(r)&&r>0?r:null,u=Number.isInteger(a)&&a>0?a:null,p=Yt===c&&_t===i&&zt===s&&Kt===d&&Qt===l&&Xt===u;Yt=e||"",_t=t||"",zt=Number.isInteger(n)?n:null,Kt=Number.isInteger(o)&&o>0?o:null,Qt=Number.isInteger(r)&&r>0?r:null,Xt=Number.isInteger(a)&&a>0?a:null,p||(V&&(V.textContent=e||"Not detected"),J&&(J.textContent=t||"Not detected"),Y&&(Y.textContent=Number.isInteger(n)?String(n):"-"),Xr(Se,Number.isInteger(n)?String(n):"-"),lr())},pr=()=>{Wn&&(window.clearTimeout(Wn),Wn=null)},hr=(e,t)=>{e&&(e.hidden=t)},mr=e=>{Xr(be,e)},yr=e=>{Xr(ee,e)},wr=(e="Select a project and book to analyse manuscript structure.")=>{if(un=null,te){te.innerHTML="";const e=document.createElement("p");e.textContent="No preview generated.",te.append(e)}yr(e),gr()},fr=(e=un)=>((e=un)=>Wa.flatMap(t=>Array.isArray(e?.[t.key])?e[t.key]:[]))(e).filter(e=>"couldLink"===e.category||"wouldCreateChapters"===e.category||"wouldCreateScenes"===e.category),gr=()=>{Z&&(Z.disabled=xn||0===fr().length)},Sr=()=>{X&&(X.disabled=xn||!ia()||!sa()),gr()},Ir=()=>{De&&(De.textContent=Zt?`Editing links for: ${Kn||_t||"Current scene"}`:"Link a PlotDirector scene first.")},Cr=()=>{const e=Ln||!Zt,t=e||!en||Rn;ge&&(ge.disabled=t),Pe&&(Pe.disabled=e),Le&&(Le.disabled=e);for(const t of[Ee,Ne])for(const n of t?[...t.querySelectorAll("input[type='checkbox']")]:[])n.disabled=e},br=e=>{"Live"!==e&&"Manual"!==e||(Nn=e),Xr(_,e||Nn||"Manual")},kr=(e,t="")=>{Ln=!!e,Ln&&(pr(),Lo()),Xr(_,Ln?"Stale":Nn),Cr(),t&&(ir(t),Dr(t))},vr=(e,t=null,n="")=>{Zt=Number.isInteger(e)&&e>0?e:null,en=Number.isInteger(t)&&t>0?t:null,tn=n||"",Zt!==Mn&&(On=null),Zt||(pr(),Lo()),Cr(),mr(Ln?"Refresh Current Scene before syncing.":Zt?"Ready to sync.":"No resolved PlotDirector scene."),Dr(Ln?"Refresh Current Scene before saving.":Zt?"Ready to save.":"Link a PlotDirector scene first."),Ir(),lr()},xr=e=>{G&&(G.disabled=e,G.textContent=e?"Refreshing...":"Refresh Current Scene")},Er=e=>null==e||""===e?"-":String(e),Nr=e=>{if(!e)return"-";const t=e instanceof Date?e:new Date(e);if(Number.isNaN(t.getTime()))return"-";const n=new Date;return`Last synced: ${t.toDateString()===n.toDateString()?"Today":t.toLocaleDateString()} ${t.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"})}`},Lr=e=>{hn=e||null;const t=hn?.lastSyncUtc||hn?.manuscriptDocument?.lastSyncUtc;Xr(fe,Nr(t)),Xr(Ce,Nr(t))},Pr=()=>{mn=null,yn=null,wn=null,Po(),Lr(null)},qr=()=>{yn=null,wn=null},Dr=e=>{Xr(qe,e)},Ar=e=>{Xr(Be,e)},$r=e=>{Xr(We,e)},Tr=()=>!!sa()&&!!Yt&&!en,jr=()=>!!sa()&&!!_t&&Number.isInteger(en)&&en>0,Wr=()=>{hr(Ae,!0),$r(""),Te&&(Te.disabled=!0,Te.textContent="Create Chapter in PlotDirector"),je&&(je.disabled=!0,je.textContent="Link to Existing Chapter")},Rr=(e="")=>{Xr($e,Er(Yt)),hr(Ae,!1),$r(e);const t=Tr();Te&&(Te.disabled=!t,Te.textContent="Create Chapter in PlotDirector"),je&&(je.disabled=!t,je.textContent="Link to Existing Chapter")},Ur=()=>{hr(Re,!0),Ar(""),Oe&&(Oe.disabled=!0,Oe.textContent="Create Scene in PlotDirector"),He&&(He.disabled=!0,He.textContent="Link to Existing Scene")},Mr=(e="")=>{Xr(Ue,Er(Yt)),Xr(Me,Er(_t)),hr(Re,!1),Ar(e);const t=jr();Oe&&(Oe.disabled=!t,Oe.textContent="Create Scene in PlotDirector"),He&&(He.disabled=!t,He.textContent="Link to Existing Scene")},Or=e=>{sr(e),hr(de,!0),hr(ke,!0),hr(xe,!1),Wr(),Ur(),tn="",Kn="",Qn="",nn=Xt?"SceneID Anchor":Qt?"ChapterID Anchor":"Title Match",rn=!1,Zn={characters:[],assets:[],locations:[],primaryLocationId:null},Br(Ee,[],"character"),Br(Ne,[],"asset"),Gr([],null,!1),vr(null),Xr(Ie,"-"),Xr(le,"-"),Xr(ue,"-"),Xr(pe,"-"),Xr(he,"-"),Xr(me,"-"),Xr(we,"-"),hr(ye,!0),lr(),Ir()},Hr=(e,t)=>"asset"===t?e?.assetId||e?.AssetId||e?.storyAssetId||e?.StoryAssetId||0:"location"===t?e?.locationId||e?.LocationId||0:e?.characterId||e?.CharacterId||0,Br=(e,t,n,r=!1)=>{if(!e)return;e.innerHTML="";const a=Array.isArray(t)?t:[];if(0===a.length){const t=document.createElement("p");return t.className="word-companion-empty-list",t.textContent="None",void e.append(t)}for(const t of a){const a=Number.parseInt(Hr(t,n),10);if(!Number.isInteger(a)||a<=0)continue;const o=document.createElement("label");o.className="word-companion-check-item";const c=document.createElement("input");c.type="checkbox",c.value=String(a),c.checked=!!t.linked,c.disabled=!r;const i=document.createElement("span");i.textContent=t.name||"Unnamed",o.append(c,i),e.append(o)}},Gr=(e,t,n=!1)=>{if(!Le)return;Le.innerHTML="";const r=document.createElement("option");r.value="",r.textContent="None",Le.append(r);const a=Number.parseInt(t||"",10);for(const t of Array.isArray(e)?e:[]){const e=Number.parseInt(Hr(t,"location"),10);if(!Number.isInteger(e)||e<=0)continue;const n=document.createElement("option");n.value=String(e),n.textContent=t.name||"Unnamed",n.selected=e===a,Le.append(n)}Le.disabled=!n},Fr=e=>String(e||"").trim().replace(/\s+/g," "),Vr=(e,t)=>{const n=Fr(e);if(!n)return"";const r=new RegExp(`^${"scene"===t?"scene":"chapter"}\\s+(?:\\d+|[ivxlcdm]+|one|two|three|four|five|six|seven|eight|nine|ten|eleven|twelve|thirteen|fourteen|fifteen|sixteen|seventeen|eighteen|nineteen|twenty)\\s*(?::|-|\\u2013|\\u2014)\\s*`,"i");return Fr(n.replace(r,""))||n},Jr=e=>{const t=t=>Object.prototype.hasOwnProperty.call(e,t);t("projectId")&&Xr(yt,Er(e.projectId)),t("projectTitle")&&Xr(wt,Er(e.projectTitle)),t("bookId")&&Xr(ft,Er(e.bookId)),t("bookTitle")&&Xr(gt,Er(e.bookTitle)),t("detectedChapter")&&Xr(St,Er(e.detectedChapter)),t("detectedScene")&&Xr(It,Er(e.detectedScene)),t("requestChapter")&&Xr(Ct,Er(e.requestChapter)),t("requestScene")&&Xr(bt,Er(e.requestScene)),t("result")&&Xr(kt,Er(e.result)),t("chapterId")&&Xr(vt,Er(e.chapterId)),t("sceneId")&&Xr(xt,Er(e.sceneId))},Yr=async e=>{if(wn===e&&Array.isArray(yn?.chapters))return yn.chapters;const t=await co(`/api/word-companion/books/${e}/structure`);return wn=e,yn=t||null,Array.isArray(t?.chapters)?t.chapters:[]},_r=async e=>{const t=await co(`/api/word-companion/books/${e}/chapters`);return Array.isArray(t?.chapters)?t.chapters:[]},zr=e=>{if(Number.isInteger(en)&&en>0){const t=e.find(e=>e.chapterId===en);if(t)return t}const t=Vr(Yt,"chapter").toLocaleLowerCase();return t&&e.find(e=>Vr(e.title,"chapter").toLocaleLowerCase()===t)||null},Kr=async()=>{const e=sa();return e?zr(await Yr(e.bookId)):null},Qr=async(e,t,n,r,a)=>{const o=await co(`/api/word-companion/scenes/${t}/companion`);try{o.revisionStatus=await(async(e,t)=>{const n=await co(`/api/word-companion/books/${e}/structure`),r=Array.isArray(n?.chapters)?n.chapters:[];for(const e of r){const n=(Array.isArray(e.scenes)?e.scenes:[]).find(e=>e.sceneId===t);if(n)return n.revisionStatus||""}return""})(e,t)}catch{o.revisionStatus=""}var c;nn=a||"Title Match",rn=!1,kr(!1),sr("Linked to PlotDirector"),ir(""),Wr(),Ur(),vr(t,n,r),c=o,Kn=c?.sceneTitle||_t||"",Qn=c?.chapterTitle||Yt||"",Xr(le,Er(c?.sceneTitle)),Xr(ue,Er(c?.revisionStatus||c?.revisionStatusName||"Not provided")),Xr(pe,Er(c?.estimatedWords)),Xr(he,Er(c?.actualWords)),Xr(Ie,Er(c?.actualWords)),Xr(me,c?.blocked?"Blocked":"Not blocked"),c?.blockedReason?(Xr(we,c.blockedReason),hr(ye,!1)):(Xr(we,"-"),hr(ye,!0)),ve&&(ve.textContent=c?.writingBrief||"No writing brief has been added for this scene."),Zn={characters:Array.isArray(c?.characters)?c.characters:[],assets:Array.isArray(c?.assets)?c.assets:[],locations:Array.isArray(c?.locations)?c.locations:[],primaryLocationId:c?.primaryLocationId??null},Br(Ee,Zn.characters,"character",!!Zt&&!Ln),Br(Ne,Zn.assets,"asset",!!Zt&&!Ln),Gr(Zn.locations,Zn.primaryLocationId,!!Zt&&!Ln),Ir(),Dr(Ln?"Refresh Current Scene before saving.":Zt?"Ready to save.":"No resolved PlotDirector scene."),hr(de,!1),hr(ke,!1),hr(xe,!1),lo(t,n),No(),$o()},Xr=(e,t)=>{if(e){const n=null==t?"":String(t);e.textContent!==n&&(e.textContent=n)}},Zr=e=>{const t=t=>Object.prototype.hasOwnProperty.call(e,t);t("host")&&Xr(Nt,e.host),t("platform")&&Xr(Lt,e.platform),t("ready")&&Xr(Pt,e.ready),t("wordApi")&&Xr(qt,e.wordApi),t("lastScan")&&Xr(Dt,e.lastScan),t("lastError")&&Xr(At,e.lastError),t("paragraphs")&&Xr(Rt,e.paragraphs),t("heading1")&&Xr(Ut,e.heading1),t("heading2")&&Xr(Mt,e.heading2)},ea=e=>{const t=[];return e?.name&&t.push(e.name),e?.code&&e.code!==e.name&&t.push(e.code),e?.message&&t.push(e.message),e?.debugInfo?.errorLocation&&t.push(`Location: ${e.debugInfo.errorLocation}`),t.length>0?t.join(": "):String(e)},ta=async()=>{if(!window.Office||"function"!=typeof window.Office.onReady)return Gt=!1,Ft=!1,Vt="Unavailable",Jt="Unavailable",Zr({host:Vt,platform:Jt,ready:"No",wordApi:"No"}),null;const e=await window.Office.onReady();return Gt=!0,Vt=e?.host||"Unknown",Jt=e?.platform||"Unknown",Ft=!!window.Word&&!!window.Office.HostType&&e?.host===window.Office.HostType.Word,Zr({host:Vt,platform:Jt,ready:"Yes",wordApi:Ft?"Yes":"No"}),e},na=e=>{try{const t=window.localStorage.getItem(e),n=Number.parseInt(t||"",10);return Number.isInteger(n)&&n>0?n:null}catch{return null}},ra=(e,t)=>{try{t?window.localStorage.setItem(e,String(t)):window.localStorage.removeItem(e)}catch{}},aa=(e,t)=>{if(!e)return;e.innerHTML="";const n=document.createElement("option");n.value="",n.textContent=t,e.append(n),e.disabled=!0},oa=(e,t,n,r,a)=>{if(!e)return;e.innerHTML="";const o=document.createElement("option");o.value="",o.textContent=t,e.append(o);for(const t of n){const n=document.createElement("option");n.value=String(t[r]),n.textContent=t[a],e.append(n)}e.disabled=0===n.length},ca=e=>{const t=String(e?.title||"").trim(),n=String(e?.subtitle||"").trim();return n?`${t}: ${n}`:t},ia=()=>{const e=Number.parseInt(M?.value||"",10);return Ht.find(t=>t.projectId===e)||null},sa=()=>{const e=Number.parseInt(O?.value||"",10);return Bt.find(t=>t.bookId===e)||null},da=()=>{const e=Number.parseInt(h?.value||"",10);return Ht.find(t=>t.projectId===e)||null},la=()=>{const e=Number.parseInt(m?.value||"",10);return Bt.find(t=>t.bookId===e)||null},ua=e=>Xr(S,e),pa=()=>{const e=da(),t=la(),n=Cn&&Date.now()-bn>=750;f&&(f.disabled=!e||!t||kn),w&&(w.disabled=!e||!String(y?.value||"").trim()||kn),P&&(P.disabled=!fn?.canImport||!gn||kn),x&&(x.disabled=!n||vn||0===wa().length)},ha=e=>{hr(p,!e),hr(d,e);for(const t of u)hr(t,!!e||"scene"!==t.dataset.tabPanel&&!t.classList.contains("is-active"));e||rr()},ma=()=>{if(!h)return;if(0===Ht.length)return void aa(h,"No projects available.");oa(h,"Choose a project",Ht,"projectId","title");const e=Number.parseInt(M?.value||"",10);Number.isInteger(e)&&e>0&&(h.value=String(e))},ya=(e="Select a Project and Book to begin.")=>{fn=null,gn=null,Sn=[],In=!1,Cn=!1,bn=0,hr(I,!0),hr(L,!0),hr(C,!0),hr(v,!0),I&&(I.innerHTML=""),k&&(k.innerHTML=""),Xr(b,""),ua(e),pa()},wa=()=>k?[...k.querySelectorAll("input[type='checkbox']:checked")].map(e=>String(e.value||"").trim()).filter(Boolean):[],fa=e=>{if(Sn=Array.isArray(e)?e:[],C&&k){if(k.innerHTML="",hr(C,!1),hr(v,!In||0===Sn.length),hr(x,!1),hr(E,!1),hr(N,!0),0===Sn.length)return Xr(b,"No likely major characters found."),void pa();Xr(b,`${Sn.length} likely major characters found.`);for(const e of Sn){const t=document.createElement("label");t.className="word-companion-character-candidate";const n=document.createElement("input");n.type="checkbox",n.value=e.text||"",n.checked="high"===String(e.confidence||"").trim().toLowerCase(),n.addEventListener("change",pa);const r=document.createElement("strong");r.textContent=e.text||"";const a=document.createElement("em"),o=String(e.reason||"").trim();a.textContent=o?`${Number(e.mentionCount||0).toLocaleString()} mentions · ${o}`:`${Number(e.mentionCount||0).toLocaleString()} mentions`;const c=document.createElement("span");c.className="word-companion-character-candidate-text",c.append(r,a),t.append(n,c),k.append(t)}pa()}},ga=()=>{const e=window.Office?.context?.document?.settings;if(!e)return null;const t=String(e.get(r)||"").trim(),n=Number.parseInt(e.get(a)||"",10),i=Number.parseInt(e.get(o)||"",10),s=Number.parseInt(e.get(c)||"",10);return!t||!Number.isInteger(n)||n<=0||!Number.isInteger(i)||i<=0?null:{documentGuid:t,bookId:n,projectId:i,bindingVersion:Number.isInteger(s)&&s>0?s:1}},Sa=()=>pn?.documentGuid?pn.documentGuid:window.crypto?.randomUUID?window.crypto.randomUUID():"10000000-1000-4000-8000-100000000000".replace(/[018]/g,e=>(Number(e)^16*Math.random()>>Number(e)/4).toString(16)),Ia=()=>pn?.documentGuid||ga()?.documentGuid||"",Ca=()=>{const e=ia(),t=sa();R&&(R.textContent=e?.title||"(Not connected)"),U&&(U.textContent=t?ca(t):"(Not connected)"),K&&(K.textContent=t?"":"Select a PlotDirector book before refreshing."),Sr()},ba=e=>String(e?.styleBuiltIn||e?.style||"").replace(/\s+/g,"").toLowerCase(),ka=(e,t)=>{const n=ba(e);return n===`heading${t}`||n.endsWith(`.heading${t}`)||n.includes(`heading${t}`)},va=e=>String(e||"").trim().split(/\s+/).filter(Boolean).length,xa=(e,t)=>{const n=String(e||"").match(new RegExp(`^${t}-(\\d+)$`,"i"));if(!n)return null;const r=Number.parseInt(n[1],10);return Number.isInteger(r)&&r>0?r:null},Ea=e=>{try{return Array.isArray(e?.contentControls?.items)?e.contentControls.items:[]}catch(e){return console.warn("Word paragraph content controls were not available.",e),[]}},Na=(e,t)=>{const n=Ea(e);for(const e of n){const n=xa(e.tag,t);if(n)return n}return null},La=(e,t)=>{const n=[];let r=0,a=0,o=null,c=null;e.forEach((e,t)=>{const i=String(e.text||"").trim();if(i){if(ka(e,1))return r+=1,o={index:n.length+1,paragraphIndex:t,title:i,anchorId:Na(e,"PD-CHAPTER"),scenes:[]},n.push(o),void(c=null);if(ka(e,2)){if(a+=1,!o)return;return c={index:o.scenes.length+1,paragraphIndex:t,title:i,anchorId:Na(e,"PD-SCENE"),wordCount:0},void o.scenes.push(c)}c&&(c.wordCount+=va(i))}});const i=t.find(e=>String(e.text||"").trim()),s=i?e.findIndex(e=>{return t=e,n=i,String(t?.text||"").trim()===String(n?.text||"").trim()&&ba(t)===ba(n);var t,n}):-1,d=s>=0&&n.filter(e=>e.paragraphIndex<=s).at(-1)||null,l=d&&s>=0&&d.scenes.filter(e=>e.paragraphIndex<=s).at(-1)||null;return{chapters:n,currentChapter:d,currentScene:l,paragraphCount:e.length,heading1Count:r,heading2Count:a}},Pa=new Set(["***","###"]),qa=(e,t)=>{const n=String(e?.text||"").trim();return{index:t,text:n,styleBuiltIn:e?.styleBuiltIn||"",style:e?.style||"",wordCount:va(n),chapterAnchorId:null,sceneAnchorId:null}},Da=(e,t)=>{e&&(e.endParagraphIndex=t)},Aa=(e,t)=>{e&&(e.endParagraphIndex=t,Da(e.scenes.at(-1),t))},$a=(e,t)=>{const n=(t||[]).find(e=>String(e.text||"").trim());if(!e||!n)return e?.currentParagraphIndex??-1;const r=e.paragraphs.filter(e=>((e,t)=>String(e?.text||"").trim()===String(t?.text||"").trim()&&ba(e)===ba(t))(e,n)).map(e=>e.index);return 0===r.length?e.currentParagraphIndex??-1:Number.isInteger(e.currentParagraphIndex)?r.reduce((t,n)=>Math.abs(n-e.currentParagraphIndex){if(!mn)return!1;const t=((e,t)=>!e||!Number.isInteger(t)||t<0?null:e.chapters.filter(e=>e.startParagraphIndex<=t).at(-1)||null)(mn,e),n=((e,t)=>!e||!Number.isInteger(t)||t<0?null:e.scenes.filter(e=>e.startParagraphIndex<=t).at(-1)||null)(t,e),r=t?.startParagraphIndex!==mn.currentChapter?.startParagraphIndex||n?.startParagraphIndex!==mn.currentScene?.startParagraphIndex||t?.anchorId!==mn.currentChapter?.anchorId||n?.anchorId!==mn.currentScene?.anchorId;return mn.currentParagraphIndex=e,mn.currentChapter=t,mn.currentScene=n,!!r&&(ur(t?.title,n?.title,n?.wordCount,t?.anchorId,n?.anchorId,t?.index),r)},ja=e=>{if(!Q)return;if(Q.innerHTML="",0===e.chapters.length){const e=document.createElement("p");return e.textContent="No chapters detected. Use Heading 1 for chapter titles.",void Q.append(e)}if(!e.chapters.some(e=>e.scenes.length>0)){const e=document.createElement("p");e.textContent="No scenes detected. Use Heading 2 for scene titles.",Q.append(e)}for(const t of e.chapters){const e=document.createElement("div");e.className="word-companion-outline-chapter";const n=document.createElement("strong");if(n.textContent=t.title,e.append(n),t.scenes.length>0){const n=document.createElement("ul");for(const e of t.scenes){const t=document.createElement("li");t.textContent=e.title,n.append(t)}e.append(n)}Q.append(e)}},Wa=[{key:"alreadyLinked",title:"Already Linked"},{key:"couldLink",title:"Could Link"},{key:"wouldCreateChapters",title:"Would Create Chapters"},{key:"wouldCreateScenes",title:"Would Create Scenes"},{key:"manualReview",title:"Manual Review Required"}],Ra={alreadyLinked:"Already Linked",couldLink:"Could Link",wouldCreateChapter:"Would Create Chapter",wouldCreateScene:"Would Create Scene",manualReview:"Manual Review Required"},Ua={alreadyLinked:"✓",couldLink:"~",wouldCreateChapter:"+",wouldCreateScene:"+",manualReview:"?"},Ma=(e,t)=>Vr(e,t).toLocaleLowerCase(),Oa=({category:e,action:t,type:n,wordTitle:r,match:a="",anchorStatus:o="None",matches:c=[],pdChapter:i=null,pdScene:s=null,wordChapter:d=null,wordScene:l=null,parentItem:u=null})=>({id:`${n}-${d?.index||0}-${l?.index||0}-${d?.paragraphIndex??l?.paragraphIndex??0}`,category:e,action:t,type:n,wordTitle:r,match:a,anchorStatus:o,matches:c,pdChapter:i,pdScene:s,wordChapter:d,wordScene:l,parentItem:u,result:"Pending",error:""}),Ha=(e,t)=>{Array.isArray(e[t.category])&&e[t.category].push(t)},Ba=e=>Array.isArray(e?.scenes)?e.scenes:[],Ga=(e,t,n)=>{const r=e.anchorId?`PD-CHAPTER-${e.anchorId}`:"None";if(e.anchorId){const a=t.find(t=>t.chapterId===e.anchorId);if(a){const t=Oa({category:"alreadyLinked",action:"alreadyLinked",type:"Chapter",wordTitle:e.title,match:`Chapter ${a.chapterId}: ${a.title}`,anchorStatus:r,pdChapter:a,wordChapter:e});return Ha(n,t),t}const o=Oa({category:"manualReview",action:"manualReview",type:"Chapter",wordTitle:e.title,anchorStatus:`${r} not found`,matches:[],pdChapter:null,wordChapter:e});return Ha(n,o),o}const a=t.filter(t=>Ma(t.title,"chapter")===Ma(e.title,"chapter"));if(1===a.length){const t=Oa({category:"couldLink",action:"couldLink",type:"Chapter",wordTitle:e.title,match:`Chapter ${a[0].chapterId}: ${a[0].title}`,anchorStatus:r,pdChapter:a[0],wordChapter:e});return Ha(n,t),t}if(a.length>1){const t=Oa({category:"manualReview",action:"manualReview",type:"Chapter",wordTitle:e.title,anchorStatus:r,matches:a.map(e=>`Chapter ${e.chapterId}: ${e.title}`),pdChapter:null,wordChapter:e});return Ha(n,t),t}const o=Oa({category:"wouldCreateChapters",action:"wouldCreateChapter",type:"Chapter",wordTitle:e.title,anchorStatus:r,pdChapter:null,wordChapter:e});return Ha(n,o),o},Fa=(e,t,n,r)=>{const a=e.anchorId?`PD-SCENE-${e.anchorId}`:"None";if(e.anchorId){const o=((e,t)=>{for(const n of e){const e=Ba(n).find(e=>e.sceneId===t);if(e)return{chapter:n,scene:e}}return null})(n,e.anchorId);return o?void Ha(r,Oa({category:"alreadyLinked",action:"alreadyLinked",type:"Scene",wordTitle:e.title,match:`Scene ${o.scene.sceneId}: ${o.scene.title}`,anchorStatus:a,pdChapter:o.chapter,pdScene:o.scene,wordChapter:t?.wordChapter,wordScene:e,parentItem:t})):void Ha(r,Oa({category:"manualReview",action:"manualReview",type:"Scene",wordTitle:e.title,anchorStatus:`${a} not found`,wordChapter:t?.wordChapter,wordScene:e,parentItem:t}))}if(!t?.pdChapter&&"manualReview"===t?.category)return void Ha(r,Oa({category:"manualReview",action:"manualReview",type:"Scene",wordTitle:e.title,anchorStatus:a,matches:["Parent chapter requires manual review."],wordChapter:t?.wordChapter,wordScene:e,parentItem:t}));if(!t?.pdChapter)return void Ha(r,Oa({category:"wouldCreateScenes",action:"wouldCreateScene",type:"Scene",wordTitle:e.title,anchorStatus:a,wordChapter:t?.wordChapter,wordScene:e,parentItem:t}));const o=Ba(t.pdChapter).filter(t=>Ma(t.title,"scene")===Ma(e.title,"scene"));1!==o.length?o.length>1?Ha(r,Oa({category:"manualReview",action:"manualReview",type:"Scene",wordTitle:e.title,anchorStatus:a,matches:o.map(e=>`Scene ${e.sceneId}: ${e.title}`),wordChapter:t.wordChapter,wordScene:e,parentItem:t})):Ha(r,Oa({category:"wouldCreateScenes",action:"wouldCreateScene",type:"Scene",wordTitle:e.title,anchorStatus:a,pdChapter:t.pdChapter,wordChapter:t.wordChapter,wordScene:e,parentItem:t})):Ha(r,Oa({category:"couldLink",action:"couldLink",type:"Scene",wordTitle:e.title,match:`Scene ${o[0].sceneId}: ${o[0].title}`,anchorStatus:a,pdChapter:t.pdChapter,pdScene:o[0],wordChapter:t.wordChapter,wordScene:e,parentItem:t}))},Va=e=>{const t=document.createElement("article");t.className="word-companion-preview-item";const n=document.createElement("strong");n.textContent=`${Ua[e.action]||""} ${e.type}: ${e.wordTitle}`,t.append(n);const r=document.createElement("span");if(r.textContent=`Anchor: ${e.anchorStatus||"None"}`,t.append(r),e.match){const n=document.createElement("span");n.textContent=`Match: ${e.match}`,t.append(n)}if(Array.isArray(e.matches)&&e.matches.length>0){const n=document.createElement("div");n.className="word-companion-preview-matches";const r=document.createElement("span");r.textContent="Matches:",n.append(r);const a=document.createElement("ul");for(const t of e.matches){const e=document.createElement("li");e.textContent=t,a.append(e)}n.append(a),t.append(n)}const a=document.createElement("span");if(a.textContent=`Action: ${Ra[e.action]||e.action}`,t.append(a),e.result&&"Pending"!==e.result){const n=document.createElement("span");n.textContent=e.error?`Result: ${e.result} - ${e.error}`:`Result: ${e.result}`,t.append(n)}return t},Ja=e=>{if(te){te.innerHTML="";for(const t of Wa){const n=document.createElement("section");n.className="word-companion-preview-group";const r=document.createElement("strong");r.textContent=t.title,n.append(r);const a=Array.isArray(e?.[t.key])?e[t.key]:[];if(0===a.length){const e=document.createElement("p");e.className="word-companion-empty-list",e.textContent="None",n.append(e)}else for(const e of a)n.append(Va(e));te.append(n)}gr()}},Ya=async e=>{const t=e.document.body.paragraphs,n=e.document.getSelection().paragraphs;t.load("text,styleBuiltIn,style"),n.load("text,styleBuiltIn,style"),await e.sync();try{for(const e of t.items)(ka(e,1)||ka(e,2))&&e.contentControls.load("items/tag,title");await e.sync()}catch(e){console.warn("Unable to load Word heading content controls. Continuing without PlotDirector anchors.",e)}const r=La(t.items,n.items);return r.bodyParagraphs=t.items,r},_a=async(e,t)=>{const n=e.document.body.paragraphs,r=e.document.getSelection().paragraphs;n.load("text,styleBuiltIn,style"),r.load("text,styleBuiltIn,style"),await e.sync();const a=((e,t)=>{const n=e.map(qa),r=[];let a=0,o=0,c=null,i=null,s=0;const d=(e,t=null,n=null)=>c?(Da(i,e.index-1),i={index:c.scenes.length+1,paragraphIndex:e.index,startParagraphIndex:e.index,endParagraphIndex:e.index,title:t||`Scene ${c.scenes.length+1}`,anchorId:n,wordCount:0},c.scenes.push(i),i):null;for(const e of n)e.text&&(ka(e,1)?(Aa(c,e.index-1),a+=1,c={index:r.length+1,paragraphIndex:e.index,startParagraphIndex:e.index,endParagraphIndex:e.index,title:e.text,anchorId:e.chapterAnchorId,wordCount:0,scenes:[]},r.push(c),i=null,d(e,"Scene 1",e.sceneAnchorId),s+=e.wordCount):c&&(t&&Pa.has(e.text)?(o+=1,d(e)):(c.wordCount+=e.wordCount,i&&(i.wordCount+=e.wordCount),s+=e.wordCount)));return Aa(c,n.length-1),{paragraphs:n,chapters:r,usesExplicitScenes:!!t,paragraphCount:n.length,heading1Count:a,heading2Count:o,documentWordCount:s,currentParagraphIndex:null,currentChapter:null,currentScene:null}})(n.items,t),o=$a(a,r.items);return mn=a,Ta(o),er("Cache rebuilt."),a},za=async()=>{const e=mn?.currentScene;return e&&Number.isInteger(e.startParagraphIndex)&&Number.isInteger(e.endParagraphIndex)&&Gt&&Ft&&window.Word&&"function"==typeof window.Word.run?await window.Word.run(async t=>{const n=t.document.body.paragraphs;n.load("text"),await t.sync();let r=0;const a=Math.min(e.endParagraphIndex,n.items.length-1),o=mn.currentChapter?.startParagraphIndex;for(let t=e.startParagraphIndex;t<=a;t+=1){const e=String(n.items[t]?.text||"").trim();e&&!Pa.has(e)&&t!==o&&(r+=va(e))}return e.wordCount=r,ur(mn.currentChapter?.title,e.title,r,mn.currentChapter?.anchorId,e.anchorId,mn.currentChapter?.index),r}):zt},Ka=async()=>{const e=mn?.currentScene;return e&&Number.isInteger(e.startParagraphIndex)&&Number.isInteger(e.endParagraphIndex)&&Gt&&Ft&&window.Word&&"function"==typeof window.Word.run?await window.Word.run(async t=>{const n=t.document.body.paragraphs;n.load("text"),await t.sync();const r=[],a=Math.min(e.endParagraphIndex,n.items.length-1),o=mn.currentChapter?.startParagraphIndex;for(let t=e.startParagraphIndex;t<=a;t+=1){const e=String(n.items[t]?.text||"").trim();e&&!Pa.has(e)&&t!==o&&r.push(e)}return r.join("\n")}):""},Qa=async()=>{if(ir(""),!Gt||!Ft||!window.Word||"function"!=typeof window.Word.run)return ur(null,null,null),ir("Word document access is unavailable."),Zr({lastScan:"Failure",lastError:"Word document access is unavailable."}),!1;F&&(F.disabled=!0,F.textContent="Scanning..."),ir("Scanning document structure...");try{const e=await window.Word.run(async e=>{const t=sa();return t?await _a(e,!!t.usesExplicitScenes):(mn=null,await Ya(e))});return mn||ur(e.currentChapter?.title,e.currentScene?.title,e.currentScene?.wordCount,e.currentChapter?.anchorId,e.currentScene?.anchorId,e.currentChapter?.index),Or("Not detected"),ja(e),ir(""),Zr({lastScan:"Success",lastError:"-",paragraphs:String(e.paragraphCount),heading1:String(e.heading1Count),heading2:String(e.heading2Count)}),!0}catch(e){const t=ea(e);return console.error("Unable to scan the Word document.",e),ur(null,null,null),ir(`Unable to scan the Word document: ${t}`),Zr({lastScan:"Failure",lastError:t}),!1}finally{F&&(F.disabled=!1,F.textContent="Refresh Document Structure")}},Xa=async()=>{const e=sa();if(!ia()||!e)return yr("Select a project and book to analyse manuscript structure."),!1;if(!Gt||!Ft||!window.Word||"function"!=typeof window.Word.run)return yr("Word document access is unavailable."),Zr({lastScan:"Failure",lastError:"Word document access is unavailable."}),!1;X&&(X.disabled=!0,X.textContent="Analysing..."),yr("Analysing manuscript structure...");try{const t=await window.Word.run(async e=>await Ya(e)),n=await co(`/api/word-companion/books/${e.bookId}/structure`);return ur(t.currentChapter?.title,t.currentScene?.title,t.currentScene?.wordCount,t.currentChapter?.anchorId,t.currentScene?.anchorId,t.currentChapter?.index),ja(t),un=((e,t)=>{const n={alreadyLinked:[],couldLink:[],wouldCreateChapters:[],wouldCreateScenes:[],manualReview:[]},r=Array.isArray(t?.chapters)?t.chapters:[];for(const t of Array.isArray(e?.chapters)?e.chapters:[]){const e=Ga(t,r,n);for(const a of Ba(t))Fa(a,e,r,n)}return n})(t,n),Ja(un),yr("Preview generated. No changes have been applied."),Zr({lastScan:"Success",lastError:"-",paragraphs:String(t.paragraphCount),heading1:String(t.heading1Count),heading2:String(t.heading2Count)}),!0}catch(e){return console.error("Unable to analyse manuscript structure.",e),yr("Unable to analyse manuscript structure."),Zr({lastScan:"Failure",lastError:ea(e)}),!1}finally{X&&(X.textContent="Analyse Manuscript Structure",Sr())}},Za=e=>{En&&(En(e),En=null),ut?.close?ut.close():ut&&(ut.hidden=!0)},eo=()=>{const e=((e=un)=>{const t=fr(e);return{linkChapters:t.filter(e=>"couldLink"===e.category&&"Chapter"===e.type).length,linkScenes:t.filter(e=>"couldLink"===e.category&&"Scene"===e.type).length,createChapters:t.filter(e=>"wouldCreateChapters"===e.category).length,createScenes:t.filter(e=>"wouldCreateScenes"===e.category).length,manualReview:Array.isArray(e?.manualReview)?e.manualReview.length:0}})();return(e=>{if(!pt)return;pt.innerHTML="";const t=[`Link ${e.linkChapters+e.linkScenes} chapters/scenes`,`Create ${e.createChapters} chapters`,`Create ${e.createScenes} scenes`],n=document.createElement("ul");for(const e of t){const t=document.createElement("li");t.textContent=e,n.append(t)}pt.append(n)})(e),ut?new Promise(e=>{En=e,ut.showModal?ut.showModal():ut.hidden=!1}):Promise.resolve(window.confirm(`Apply Structure Sync?\n\nThis will:\n\n- Link ${e.linkChapters+e.linkScenes} chapters/scenes\n- Create ${e.createChapters} chapters\n- Create ${e.createScenes} scenes\n\nManual review items will be skipped.`))},to=(e,t,n="")=>{e.result=t,e.error=n},no=e=>Number.isInteger(e?.wordChapter?.index)&&e.wordChapter.index>0?10*e.wordChapter.index:null,ro=e=>Number.isInteger(e?.wordScene?.index)&&e.wordScene.index>0?10*e.wordScene.index:null,ao=async(e,t)=>{const n=await io(`/api/word-companion/books/${e}/chapters`,{title:Fr(t.wordTitle),sortOrder:no(t)});if(!n?.chapterId)throw new Error("Chapter creation did not return a chapter ID.");qr(),t.pdChapter={chapterId:n.chapterId,title:n.title||t.wordTitle,sortOrder:n.sortOrder||no(t)||0,scenes:[]},t.match=`Chapter ${t.pdChapter.chapterId}: ${t.pdChapter.title}`},oo=async(e,t)=>{const n=t.pdChapter||t.parentItem?.pdChapter;if(!n?.chapterId)throw new Error("Scene parent chapter is not available.");const r=await io(`/api/word-companion/books/${e}/chapters/${n.chapterId}/scenes`,{sceneTitle:Fr(t.wordTitle),sortOrder:ro(t)});if(!r?.sceneId)throw new Error("Scene creation did not return a scene ID.");qr(),t.pdChapter=n,t.pdScene={sceneId:r.sceneId,title:t.wordTitle,sortOrder:ro(t)||0},t.match=`Scene ${t.pdScene.sceneId}: ${t.pdScene.title}`},co=async(e,t={})=>{const n=await window.fetch(e,{credentials:"same-origin",...t,headers:{Accept:"application/json",...t.headers||{}}});if(!n.ok)throw new Error(`Request failed: ${n.status}`);return await n.json()},io=(e,t)=>co(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)}),so=async(e="")=>{Cn=!1,bn=0,Sn=[],k&&(k.innerHTML=""),hr(C,!0),ha(!1),ua(""),hr(v,!0),e&&ir(e);const t=await uo();e&&t&&Yt&&ir(e)},lo=async(e=Zt,t=en)=>{const n=ia(),r=sa(),a=Ia(),o=Number.parseInt(e||"",10),c=Number.parseInt(t||"",10);if(!n||!r||!a||!Number.isInteger(o)||o<=0||!Number.isInteger(c)||c<=0)return;const i=`${n.projectId}:${r.bookId}:${o}`;if(zn!==i){zn=i;try{await io("/api/word-companion/runtime/current-scene",{documentGuid:a,projectId:n.projectId,bookId:r.bookId,chapterId:c,sceneId:o}),er("Current scene follow event sent.")}catch(e){zn="",console.debug("Unable to notify PlotDirector of current scene.",e)}}},uo=async()=>{const e=sa();if(!(e&&Gt&&Ft&&window.Word&&"function"==typeof window.Word.run))return!1;ir("Reading manuscript position...");try{qr(),await qo(!0),await Yr(e.bookId);const t=await window.Word.run(async t=>await _a(t,!!e.usesExplicitScenes));return ja(t),Zr({lastScan:"Success",lastError:"-",paragraphs:String(t.paragraphCount),heading1:String(t.heading1Count),heading2:String(t.heading2Count)}),Yt?(_t?await jo():await To(),kr(!1),br("Live"),ir(""),!0):(Or("Not detected"),kr(!1),br("Live"),ir("Manuscript linked. Click inside a chapter to show the current scene."),!0)}catch(e){return console.error("Unable to initialise bound manuscript runtime.",e),mn=null,br("Manual"),ir(`Unable to read manuscript position: ${ea(e)}`),Zr({lastScan:"Failure",lastError:ea(e)}),!1}},po=e=>e?[...e.querySelectorAll("input[type='checkbox']:checked")].map(e=>Number.parseInt(e.value||"",10)).filter(e=>Number.isInteger(e)&&e>0):[],ho=()=>{const e=Number.parseInt(Le?.value||"",10);return Number.isInteger(e)&&e>0?e:null},mo=(e,t,n,r)=>{const a=((e,t)=>Ea(e).find(e=>xa(e.tag,t))||null)(e,r),o=a||e.getRange().insertContentControl();return o.title=t,o.tag=n,o.appearance="Hidden",o},yo=async(e="PlotDirector IDs attached successfully.")=>{if(!Zt||!en)return ir("No resolved PlotDirector scene."),!1;if((Xt&&Xt!==Zt||Qt&&Qt!==en)&&!window.confirm("This scene is already linked. Replace the existing PlotDirector link?"))return!1;if(!Gt||!Ft||!window.Word||"function"!=typeof window.Word.run)return ir("Word document access is unavailable."),!1;se&&(se.disabled=!0,se.textContent="Attaching...");try{return await window.Word.run(async e=>{const t=await Ya(e);if(!t.currentChapter||!t.currentScene)throw new Error("No scene detected in Word. Use Heading 2 for scenes.");const n=t.bodyParagraphs[t.currentChapter.paragraphIndex],r=t.bodyParagraphs[t.currentScene.paragraphIndex];if(!n||!r)throw new Error("Unable to locate the current Word headings.");mo(n,"PlotDirector Chapter",`PD-CHAPTER-${en}`,"PD-CHAPTER"),mo(r,"PlotDirector Scene",`PD-SCENE-${Zt}`,"PD-SCENE"),await e.sync()}),Qt=en,Xt=Zt,rn=!1,nn="SceneID Anchor",tn="Anchor",ir(e),Zr({lastError:"-"}),lr(),!0}catch(e){return console.error("Unable to attach PlotDirector IDs.",e),ir("Unable to attach PlotDirector IDs."),Zr({lastError:ea(e)}),lr(),!1}finally{se&&(se.textContent=Xt===Zt?"Attach PlotDirector IDs":"Reattach PlotDirector IDs",lr())}},wo=async e=>{if(!en)return $r("No resolved PlotDirector chapter."),!1;if(!Gt||!Ft||!window.Word||"function"!=typeof window.Word.run)return $r("Word document access is unavailable."),!1;try{return await window.Word.run(async e=>{const t=await Ya(e);if(!t.currentChapter)throw new Error("No chapter detected in Word. Use Heading 1 for chapters.");const n=t.bodyParagraphs[t.currentChapter.paragraphIndex];if(!n)throw new Error("Unable to locate the current Word chapter heading.");mo(n,"PlotDirector Chapter",`PD-CHAPTER-${en}`,"PD-CHAPTER"),await e.sync()}),Qt=en,rn=!1,nn="ChapterID Anchor",tn="Chapter anchor",$r(e),ir(e),Zr({lastError:"-"}),lr(),!0}catch(e){return console.error("Unable to attach PlotDirector chapter ID.",e),$r("Unable to attach PlotDirector chapter ID."),Zr({lastError:ea(e)}),lr(),!1}},fo=async e=>{Wr(),await jo(),ir(e),$r(e)},go=e=>{ln&&(ln(e),ln=null),ct?.close?ct.close():ct&&(ct.hidden=!0)},So=()=>{if(!nt)return;const e=Fr(tt?.value||"").toLocaleLowerCase(),t=sn.filter(t=>!e||String(t.title||"").toLocaleLowerCase().includes(e));if(nt.innerHTML="",dn=null,rt&&(rt.disabled=!0),0===t.length){const e=document.createElement("p");return e.className="word-companion-empty-list",e.textContent="No chapters found.",void nt.append(e)}for(const e of t){const t=Number.parseInt(e.chapterId||"",10);if(!Number.isInteger(t)||t<=0)continue;const n=document.createElement("label");n.className="word-companion-scene-option";const r=document.createElement("input");r.type="radio",r.name="word-companion-link-chapter",r.value=String(t),r.addEventListener("change",()=>{dn=t,rt&&(rt.disabled=!1)});const a=document.createElement("span");a.textContent=e.title||"Untitled chapter",n.append(r,a),nt.append(n)}},Io=()=>{et?.close?et.close():et&&(et.hidden=!0)},Co=async(e,t,n)=>{const r=sa();if(!r)return Ar("Select a PlotDirector book first."),!1;await Qr(r.bookId,e,t,"Manual link","Title Match");return!!await yo(n)&&(Ar(n),Ur(),!0)},bo=e=>{cn&&(cn(e),cn=null),ze?.close?ze.close():ze&&(ze.hidden=!0)},ko=()=>{if(!Ve)return;const e=Fr(Fe?.value||"").toLocaleLowerCase(),t=an.filter(t=>!e||String(t.title||"").toLocaleLowerCase().includes(e));if(Ve.innerHTML="",on=null,Je&&(Je.disabled=!0),0===t.length){const e=document.createElement("p");return e.className="word-companion-empty-list",e.textContent="No scenes found.",void Ve.append(e)}for(const e of t){const t=Number.parseInt(e.sceneId||"",10);if(!Number.isInteger(t)||t<=0)continue;const n=document.createElement("label");n.className="word-companion-scene-option";const r=document.createElement("input");r.type="radio",r.name="word-companion-link-scene",r.value=String(t),r.addEventListener("change",()=>{on=t,Je&&(Je.disabled=!1)});const a=document.createElement("span");a.textContent=e.title||"Untitled scene",n.append(r,a),Ve.append(n)}},vo=()=>{Ge?.close?Ge.close():Ge&&(Ge.hidden=!0)},xo=()=>{Rn=!1,Cr(),Un&&(Un=!1,No(1e3))},Eo=async(e={})=>{const t=e.source||"manual";if(!Zt)return void mr("No resolved PlotDirector scene.");if(!en)return void mr("No resolved PlotDirector chapter.");if(Ln)return void mr("Refresh Current Scene before syncing.");const n=sa(),r=Ia();if(!n||!r)return void mr("Bound manuscript metadata is unavailable.");if(Rn)return Un=!0,void er("Scene sync deferred; sync already running.");pr(),Rn=!0,Un=!1;let a=zt;try{a=await za()}catch(e){return mr("Sync failed"),Zr({lastError:ea(e)}),er("Scene sync failed."),void xo()}if(!Number.isInteger(a)||a<0)return mr("Sync failed"),er("Scene sync failed."),void xo();if(Mn===Zt&&On===a)return mr("Synced"),er("Sync skipped (count unchanged)."),void xo();er("Scene word count changed."),ge&&(ge.disabled=!0,ge.textContent="Syncing..."),mr("Syncing..."),er(`Scene sync started (${t}).`);try{const e=await io("/api/word-companion/runtime/scene-word-count",{documentGuid:r,bookId:n.bookId,chapterId:en,sceneId:Zt,wordCount:a}),t=e?.actualWords??a,o=new Date;Mn=Zt,On=t,Xr(Ie,Er(t)),Xr(he,Er(t)),Xr(Ce,Nr(o)),Xr(fe,Nr(o)),mr("Synced"),er("Scene sync succeeded.")}catch(e){mr("Sync failed"),Zr({lastError:ea(e)}),er("Scene sync failed.")}finally{ge&&(ge.textContent="Sync Current Scene"),xo()}},No=(e=4e3)=>{pr(),Zt&&en&&!Ln&&!Rn&&(Wn=window.setTimeout(()=>{Wn=null,Eo({source:"automatic"})},e))},Lo=()=>{Hn&&(window.clearTimeout(Hn),Hn=null)},Po=()=>{Fn=null,Vn="",Jn=[],Yn=null,_n="",Lo()},qo=async(e=!1)=>{const t=ia(),n=Ia();if(!t||!n)return Jn=[],[];if(!e&&Fn===t.projectId&&Vn===n&&Jn.length>0)return Jn;const r=await co(`/api/word-companion/runtime/characters?projectId=${encodeURIComponent(t.projectId)}&documentGuid=${encodeURIComponent(n)}`);return Fn=t.projectId,Vn=n,Jn=Array.isArray(r?.characters)?r.characters:[],er("Character alias cache refreshed."),Jn},Do=(e,t)=>{const n=String(t||"").trim();if(!n)return!1;const r=(a=n,String(a||"").replace(/[.*+?^${}()|[\]\\]/g,"\\$&")).replace(/\s+/g,"\\s+");var a;return new RegExp(`(^|[^\\p{L}\\p{N}_])${r}(?=$|[^\\p{L}\\p{N}_])`,"iu").test(e)},Ao=async()=>{if(Hn=null,Zt&&!Ln&&Ia()){if(Bn)return Gn=!0,void er("Character suggestion detection deferred; detection already running.");Bn=!0,Gn=!1;try{const[e,t]=await Promise.all([Ka(),qo()]),n=((e,t)=>{if(!e||!Array.isArray(t)||0===t.length)return[];const n=new Map;for(const r of t){const t=Number.parseInt(r.characterId||"",10);!Number.isInteger(t)||t<=0||n.has(t)||Do(e,r.matchText)&&n.set(t,r.name||r.matchText||"Character")}return[...n.entries()].map(([e,t])=>({characterId:e,name:t}))})(e,t),r=n.map(e=>e.characterId),a=r.slice().sort((e,t)=>e-t).join(",");if(!a||Yn===Zt&&_n===a)return void er("Character suggestions skipped.");const o=await io("/api/word-companion/runtime/character-suggestions",{documentGuid:Ia(),sceneId:Zt,characterIds:r});if(Yn=Zt,_n=a,(o?.createdCount||0)>0){const e=n.slice(0,3).map(e=>e.name).join(", "),t=n.length>3?" +"+(n.length-3):"";ir(e?`Characters detected: ${e}${t}`:o.message)}er(o?.message||"Character suggestions submitted.")}catch(e){console.error("Unable to detect character suggestions.",e),Zr({lastError:ea(e)})}finally{Bn=!1,Gn&&(Gn=!1,$o(1500))}}},$o=(e=2500)=>{Lo(),!Zt||Ln||Bn?Bn&&(Gn=!0):Hn=window.setTimeout(()=>{Ao()},e)},To=async()=>{const e=ia(),t=sa(),n=Vr(Yt,"chapter");if(Jr({projectId:e?.projectId,projectTitle:e?.title,bookId:t?.bookId,bookTitle:t?ca(t):void 0,detectedChapter:Yt,detectedScene:_t,requestChapter:n,requestScene:"",result:"Not run",chapterId:null,sceneId:null}),!t)return Or("Not detected"),ir("Select a PlotDirector book first."),!1;if(!Yt)return Or("Not detected"),ir("No chapter detected in Word. Use Heading 1 for chapters."),!1;Or("Not detected");try{const e=await _r(t.bookId),r=Qt?e.find(e=>e.chapterId===Qt):null,a=n.toLocaleLowerCase(),o=a?e.find(e=>Vr(e.title,"chapter").toLocaleLowerCase()===a):null,c=r||o;return c?(Wr(),vr(null,c.chapterId,r?"Chapter anchor":"Chapter title"),nn=r?"ChapterID Anchor":"Title Match",sr("Chapter linked to PlotDirector"),ir("No scene detected in Word. Use Heading 2 for scenes."),Jr({result:"Chapter matched",chapterId:c.chapterId,sceneId:null}),!0):(vr(null),sr("Chapter not found in PlotDirector."),ir("Chapter not found in PlotDirector."),Jr({result:"Chapter not matched",chapterId:null,sceneId:null}),Rr("Chapter not found in PlotDirector."),!1)}catch(e){return Or("Not found in PlotDirector"),Zr({lastError:ea(e)}),ir("Unable to load PlotDirector chapter data."),!1}},jo=async()=>{const e=ia(),t=sa(),n=Vr(Yt,"chapter"),r=Vr(_t,"scene");if(Jr({projectId:e?.projectId,projectTitle:e?.title,bookId:t?.bookId,bookTitle:t?ca(t):void 0,detectedChapter:Yt,detectedScene:_t,requestChapter:n,requestScene:r,result:"Not run",chapterId:null,sceneId:null}),dr({anchorType:Xt?"SceneID Anchor":Qt?"ChapterID Anchor":"Title Match",storedSceneId:Xt,storedChapterId:Qt,resolutionMethod:"-"}),!t)return Or("Not detected"),ir("Select a PlotDirector book first."),Jr({result:"Error"}),!1;if(!Yt||!_t)return Or("Not detected"),ir("No scene detected in Word. Use Heading 2 for scenes."),Jr({result:"Error"}),!1;ne&&(ne.disabled=!0,ne.textContent="Refreshing...");const a=()=>{ne&&(ne.disabled=!1,ne.textContent="Refresh PlotDirector Scene")};Or("Not detected"),ir("Resolving PlotDirector scene...");try{if(Xt){const e=await(async(e,t)=>{const n=await co(`/api/word-companion/books/${e}/structure`),r=Array.isArray(n?.chapters)?n.chapters:[];for(const e of r){const n=Array.isArray(e.scenes)?e.scenes:[];for(const r of n)if(t(e,r))return{chapter:e,scene:r}}return null})(t.bookId,(e,t)=>t.sceneId===Xt);if(e)return Jr({result:"Matched",chapterId:e.chapter.chapterId,sceneId:e.scene.sceneId}),await Qr(t.bookId,e.scene.sceneId,e.chapter.chapterId,"Anchor","SceneID Anchor"),!0;rn=!0,nn="SceneID Anchor",sr("Not found in PlotDirector"),ir("Stored PlotDirector ID is invalid."),Jr({result:"Error",chapterId:Qt,sceneId:Xt}),dr({anchorType:"SceneID Anchor",storedSceneId:Xt,storedChapterId:Qt,resolutionMethod:"Anchor"})}if(Qt){const e=(await Yr(t.bookId)).find(e=>e.chapterId===Qt),n=e?(Array.isArray(e.scenes)?e.scenes:[]).find(e=>Vr(e.title,"scene").toLocaleLowerCase()===r.toLocaleLowerCase()):null;if(n)return Jr({result:"Matched",chapterId:e.chapterId,sceneId:n.sceneId}),await Qr(t.bookId,n.sceneId,e.chapterId,"Anchor","ChapterID Anchor"),!0;e&&!Xt?(nn="ChapterID Anchor",vr(null,Qt,"Chapter anchor"),Jr({result:"Chapter matched",chapterId:Qt,sceneId:null})):Xt||(nn="ChapterID Anchor",Jr({result:"Chapter anchor not found",chapterId:Qt,sceneId:null}))}const e=await io(`/api/word-companion/books/${t.bookId}/resolve-scene`,{chapterTitle:n,sceneTitle:r});if(!e?.matched||!e.sceneId){const t=rn,n=Number.parseInt(e?.chapterId||"",10),r=Number.isInteger(en)&&en>0?en:null,o=Number.isInteger(n)&&n>0?n:r,c=!!e?.chapterMatched||!!o;return Or("Not found in PlotDirector"),rn=t,c&&(vr(null,o,o===r?"Chapter anchor":"Chapter title"),sr("Scene not found in PlotDirector.")),ir(t?"Stored PlotDirector ID is invalid.":c?"Scene not found in PlotDirector.":"This chapter does not exist in PlotDirector. Create or link the chapter first."),Jr({result:"Not matched",chapterId:c?o:e?.chapterId,sceneId:e?.sceneId}),t||(c?(Wr(),Mr("Scene not found in PlotDirector.")):(Ur(),Rr("Chapter not found in PlotDirector."))),a(),!1}const o=rn;return Jr({result:o?"Matched by title fallback":"Matched",chapterId:e.chapterId,sceneId:e.sceneId}),await Qr(t.bookId,e.sceneId,e.chapterId,o?"Title fallback":"Title","Title Match"),o&&(rn=!0,ir("Stored PlotDirector ID is invalid."),lr()),!0}catch(e){const t=rn;return Zr({lastError:ea(e)}),Or("Not found in PlotDirector"),rn=t,ir(t?"Stored PlotDirector ID is invalid.":"Unable to load PlotDirector scene data."),Jr({result:"Error"}),!1}finally{a()}},Wo=async()=>{if(Pn=null,jn)return An=!0,void er("Runtime update deferred; update already running.");if(!Ot||!sa())return qn=!1,void er("Runtime update skipped.");if(!Gt||!Ft||!window.Word||"function"!=typeof window.Word.run)return qn=!1,br("Manual"),void ir("Automatic scene tracking is unavailable in this Word version. Use Refresh Current Scene.");if(!mn)return qn=!1,br("Manual"),void ir("Document structure is not cached yet. Use Refresh Current Scene.");const e=Date.now()-Dn;if(qn&&e<$n)return er("Runtime update skipped (typing active)."),void Ro($n-e);jn=!0,qn=!1,An=!1,br("Updating..."),er("Runtime update executed.");try{const e=await window.Word.run(async e=>await(async e=>{const t=e.document.getSelection().paragraphs;return t.load("text,styleBuiltIn,style"),await e.sync(),t.items})(e)),t=$a(mn,e),n=Ta(t);if(await za(),!n)return kr(!1),br("Current scene updated"),No(),void $o();_t?await jo():await To(),kr(!1),br("Current scene updated"),ir("Current scene updated."),No(),$o()}catch(e){console.error("Unable to refresh current scene from Word selection.",e),Zr({lastError:ea(e)}),kr(!0,"The Word cursor is now in a different scene. Refresh Current Scene before saving.")}finally{jn=!1,(An||qn)&&(An=!1,Ro($n))}},Ro=(e=1200)=>{Pn&&window.clearTimeout(Pn),Pn=window.setTimeout(Wo,Math.max(0,e)),br("Waiting for typing to pause"),er("Runtime update scheduled.")},Uo=()=>{((e="selection",t=1200)=>{if(qn=!0,Dn=Date.now(),pr(),Lo(),er(`${e} changed.`),jn)return An=!0,void br("Waiting for typing to pause");Ro(t)})("Selection")},Mo=()=>{if(Tn&&window.Office?.context?.document&&"function"==typeof window.Office.context.document.removeHandlerAsync&&window.Office?.EventType?.DocumentSelectionChanged)try{window.Office.context.document.removeHandlerAsync(window.Office.EventType.DocumentSelectionChanged,{handler:Uo}),Tn=!1}catch(e){console.warn("Unable to remove Word selection tracking handler.",e)}},Oo=async(e,n)=>{if(mn=null,qr(),!e)return Bt=[],aa(O,"Select a project first"),aa(m,"Select a project first"),cr(""),ra(t,null),Ca(),Or("Not detected"),void wr();aa(O,"Loading books..."),cr(""),Or("Not detected"),wr("Select a book to analyse manuscript structure.");try{const r=await co(`/api/word-companion/projects/${e}/books`);if(Bt=Array.isArray(r.books)?r.books:[],0===Bt.length)return aa(O,"No books available."),aa(m,"No books available."),cr("No books available."),ra(t,null),Ca(),void ya("No books available.");oa(O,"Choose a book",Bt.map(e=>({...e,displayTitle:ca(e)})),"bookId","displayTitle");const a=Bt.find(e=>e.bookId===n);a&&O?(O.value=String(a.bookId),ra(t,a.bookId)):ra(t,null),((e=null)=>{if(!m)return;if(0===Bt.length)return void aa(m,"No books available.");oa(m,"Choose a book",Bt.map(e=>({...e,displayTitle:ca(e)})),"bookId","displayTitle");const t=e||Number.parseInt(O?.value||"",10),n=Bt.find(e=>e.bookId===t);n&&(m.value=String(n.bookId)),pa()})(a?.bookId||n),Ca(),Or((sa(),"Not detected")),wr(sa()?"Ready to analyse manuscript structure.":"Select a book to analyse manuscript structure."),ya(la()?"Ready to scan manuscript structure.":"Select a Book to begin.")}catch{Bt=[],aa(O,"Unable to load books."),aa(m,"Unable to load books."),cr("Unable to load books."),ra(t,null),Ca(),Or("Not detected"),wr("Unable to load books."),ya("Unable to load books.")}};for(const e of l)e.addEventListener("click",()=>nr(e.dataset.tabButton));rr(),M?.addEventListener("change",async()=>{const n=Number.parseInt(M.value||"",10);Pr(),h&&Number.isInteger(n)&&n>0&&(h.value=String(n)),ra(e,Number.isInteger(n)&&n>0?n:null),ra(t,null),Or("Not detected"),wr(),ya("Select a Book to begin."),await Oo(n,null)}),O?.addEventListener("change",()=>{const e=Number.parseInt(O.value||"",10);Pr(),ra(t,Number.isInteger(e)&&e>0?e:null),m&&Number.isInteger(e)&&e>0&&(m.value=String(e)),Ca(),Or("Not detected"),wr(sa()?"Ready to analyse manuscript structure.":"Select a book to analyse manuscript structure."),ya(la()?"Ready to scan manuscript structure.":"Select a Book to begin.")}),h?.addEventListener("change",async()=>{const n=Number.parseInt(h.value||"",10);Pr(),M&&Number.isInteger(n)&&n>0&&(M.value=String(n)),ra(e,Number.isInteger(n)&&n>0?n:null),ra(t,null),ya("Select a Book to begin."),await Oo(n,null)}),m?.addEventListener("change",()=>{const e=Number.parseInt(m.value||"",10);Pr(),O&&Number.isInteger(e)&&e>0&&(O.value=String(e)),ra(t,Number.isInteger(e)&&e>0?e:null),Ca(),ya(la()?"Ready to scan manuscript structure.":"Select a Book to begin.")}),y?.addEventListener("input",pa),w?.addEventListener("click",async()=>{const e=da(),t=String(y?.value||"").trim();if(e&&t){w.disabled=!0,ua("Creating Book...");try{const n=await io(`/api/word-companion/projects/${e.projectId}/books`,{title:t});y&&(y.value=""),M&&(M.value=String(e.projectId)),await Oo(e.projectId,n.bookId),m&&(m.value=String(n.bookId)),ua("Ready to scan manuscript structure.")}catch(e){console.error("Unable to create Book from Word Companion.",e),ua(`Unable to create Book: ${ea(e)}`)}finally{pa()}}else pa()}),f?.addEventListener("click",async()=>{const e=da(),t=la();if(e&&t)if(Gt&&Ft&&window.Word&&"function"==typeof window.Word.run){f&&(f.disabled=!0,f.textContent="Scanning..."),ua("Scanning manuscript structure...");try{const n=await window.Word.run(async e=>{const n=e.document.body.paragraphs;return n.load("text,styleBuiltIn,style"),await e.sync(),((e,t)=>{const n=[];let r=null,a=null,o=0;const c=[],i=new Set(["***","###"]),s=()=>{if(!r)return null;const e={title:`Scene ${r.scenes.length+1}`,sortOrder:10*(r.scenes.length+1),wordCount:0};return r.scenes.push(e),e};return e.forEach(e=>{const d=String(e.text||"").trim();if(!d)return;if(c.push(d),ka(e,1))return r={title:d,sortOrder:10*(n.length+1),wordCount:0,scenes:[]},n.push(r),a=s(),void(o+=va(d));if(!r||!a)return;if(t&&i.has(d))return void(a=s());const l=va(d);r.wordCount+=l,a.wordCount+=l,o+=l}),{chapters:n,chapterCount:n.length,sceneCount:n.reduce((e,t)=>e+t.scenes.length,0),wordCount:o,documentText:c.join("\n")}})(n.items,!!t.usesExplicitScenes)});gn=n,In=!1;const r=await io("/api/word-companion/manuscript/analyse",{projectId:e.projectId,bookId:t.bookId,documentGuid:Sa(),chapterCount:n.chapterCount,sceneCount:n.sceneCount,wordCount:n.wordCount});fn=r,(e=>{if(!I)return;I.innerHTML="";const t=document.createElement("strong");t.textContent="Manuscript Analysis",I.append(t);const n=document.createElement("dl"),r=[["Project",e.projectTitle],["Book",ca({title:e.bookTitle,subtitle:e.bookSubtitle})],["Chapters",Number(e.chapterCount||0).toLocaleString()],["Scenes",Number(e.sceneCount||0).toLocaleString()],["Words",Number(e.wordCount||0).toLocaleString()]];for(const[e,t]of r){const r=document.createElement("dt");r.textContent=e;const a=document.createElement("dd");a.textContent=t||"-",n.append(r,a)}I.append(n),hr(I,!1),hr(L,!1),ua(e.message||"Preview generated."),pa()})(r);try{const t=await io("/api/word-companion/manuscript/discover-characters",{projectId:e.projectId,documentText:n.documentText||""});Sn=Array.isArray(t?.candidates)?t.candidates:[],hr(C,!0),hr(v,!0)}catch(e){console.error("Unable to discover character candidates.",e),Sn=[],hr(C,!0),hr(v,!0)}Zr({lastScan:"Success",lastError:"-",paragraphs:"-",heading1:String(n.chapterCount),heading2:"-"})}catch(e){console.error("Unable to scan manuscript for first-run import.",e),ya(`Unable to scan manuscript: ${ea(e)}`),Zr({lastScan:"Failure",lastError:ea(e)})}finally{f&&(f.textContent="Scan Manuscript"),pa()}}else ya("Word document access is unavailable.");else ya("Select a Project and Book to begin.")}),P?.addEventListener("click",async()=>{const n=da(),i=la();if(!(n&&i&&gn&&fn?.canImport))return void pa();let s=!1;if(!fn.requiresReplaceConfirmation||(s=await new Promise(e=>{if(!D||"function"!=typeof D.showModal)return void e(window.confirm("This Book already contains planned chapters and scenes.\n\nImporting this manuscript will replace the planned structure.\n\nContinue?"));const t=t=>{A?.removeEventListener("click",n),$?.removeEventListener("click",r),D?.removeEventListener("cancel",a),D?.close(),e(t)},n=()=>t(!0),r=()=>t(!1),a=e=>{e.preventDefault(),t(!1)};A?.addEventListener("click",n),$?.addEventListener("click",r),D?.addEventListener("cancel",a),D.showModal()}),s)){kn=!0,pa(),ua("Importing manuscript structure...");try{const l=Sa(),u=await io("/api/word-companion/manuscript/import",{projectId:n.projectId,bookId:i.bookId,documentGuid:l,bindingVersion:1,replacePlanned:s,chapters:gn.chapters});if(!u.imported)return fn={...fn,canImport:!u.requiresReplaceConfirmation,requiresReplaceConfirmation:!!u.requiresReplaceConfirmation,message:u.message||fn.message},ua(u.message||"Import was not completed."),void pa();const p=u.manuscriptDocument;await(d={documentGuid:p?.documentGuid||l,bookId:u.bookId,projectId:u.projectId,bindingVersion:p?.bindingVersion||1},new Promise((e,t)=>{const n=window.Office?.context?.document?.settings;n?(n.set(r,d.documentGuid),n.set(a,String(d.bookId)),n.set(o,String(d.projectId)),n.set(c,String(d.bindingVersion||1)),n.saveAsync(n=>{n.status===window.Office.AsyncResultStatus.Succeeded?e():t(n.error||new Error("Unable to save Word document metadata."))})):t(new Error("Word document settings are unavailable."))})),pn={documentGuid:p?.documentGuid||l,bookId:u.bookId,projectId:u.projectId,bindingVersion:p?.bindingVersion||1},ra(e,u.projectId),ra(t,u.bookId),M&&(M.value=String(u.projectId));const h=Sn;await Oo(u.projectId,u.bookId),ar("Connected"),In=!0,Cn=h.length>0,bn=Cn?Date.now():0,Sn=h,h.length>0?(ha(!0),fa(h),hr(L,!0),hr(v,!1),ua(u.message||"Manuscript structure imported."),ir(u.message||"Manuscript structure imported."),window.setTimeout(pa,750)):await so(u.message||"Manuscript structure imported.")}catch(e){console.error("Unable to import manuscript structure.",e),ua(`Unable to import manuscript: ${ea(e)}`)}finally{kn=!1,pa()}var d}else ua("Import cancelled.")}),x?.addEventListener("click",async()=>{const e=da()||ia(),t=wa();if(!Cn||Date.now()-bn<750||!e||0===t.length)pa();else{vn=!0,pa(),Xr(b,"Creating selected characters...");try{const n=await io("/api/word-companion/manuscript/create-discovered-characters",{projectId:e.projectId,candidateNames:t});ir(n.message||"Characters created."),Xr(b,`${n.createdCount||0} created, ${n.skippedCount||0} already existed.`),await so(n.message||"Characters created.")}catch(e){console.error("Unable to create discovered characters.",e),Xr(b,`Unable to create characters: ${ea(e)}`)}finally{vn=!1,pa()}}}),E?.addEventListener("click",()=>so("Character creation skipped.")),N?.addEventListener("click",()=>so()),g?.addEventListener("click",()=>ha(!1)),q?.addEventListener("click",()=>ya("Import cancelled.")),F?.addEventListener("click",Qa),X?.addEventListener("click",Xa),Z?.addEventListener("click",async()=>{const e=sa();if(!e||0===fr().length||xn)return void gr();if(!await eo())return;xn=!0,Sr(),yr("Applying structure sync...");const t={createdChapters:0,createdScenes:0,linkedChapters:0,linkedScenes:0,skipped:Array.isArray(un?.manualReview)?un.manualReview.length:0,failed:0},n=fr().filter(e=>"couldLink"===e.category&&"Chapter"===e.type),r=fr().filter(e=>"wouldCreateChapters"===e.category),a=fr().filter(e=>"couldLink"===e.category&&"Scene"===e.type),o=fr().filter(e=>"wouldCreateScenes"===e.category),c=[];let i="";const s=(e,t)=>{c.push({item:e,counterName:t})},d=async(e,n)=>{try{await(async e=>{if(!Gt||!Ft||!window.Word||"function"!=typeof window.Word.run)throw new Error("Word document access is unavailable.");await window.Word.run(async t=>{const n=await Ya(t),r="Chapter"===e.type?e.wordChapter:e.wordScene,a=Number.isInteger(r?.paragraphIndex)?n.bodyParagraphs[r.paragraphIndex]:null;if(!a)throw new Error("Unable to locate the Word heading.");if("Chapter"===e.type){const t=e.pdChapter?.chapterId;if(!t)throw new Error("Chapter ID is not available.");mo(a,"PlotDirector Chapter",`PD-CHAPTER-${t}`,"PD-CHAPTER")}else{const t=e.pdScene?.sceneId;if(!t)throw new Error("Scene ID is not available.");mo(a,"PlotDirector Scene",`PD-SCENE-${t}`,"PD-SCENE")}await t.sync()})})(e),to(e,"Success"),t[n]+=1}catch(n){to(e,"Failed",ea(n)),t.failed+=1}};try{for(const e of n)s(e,"linkedChapters");for(const n of r)try{await ao(e.bookId,n),s(n,"createdChapters")}catch(e){to(n,"Failed",ea(e)),t.failed+=1}for(const e of a)s(e,"linkedScenes");for(const n of o)try{await oo(e.bookId,n),s(n,"createdScenes")}catch(e){to(n,"Failed",ea(e)),t.failed+=1}for(const e of c)await d(e.item,e.counterName);for(const e of un.manualReview||[])to(e,"Skipped");Ja(un),i=(e=>`Structure Sync Complete. Created: ${e.createdChapters} Chapters, ${e.createdScenes} Scenes. Linked: ${e.linkedChapters} Chapters, ${e.linkedScenes} Scenes. Skipped: ${e.skipped} Manual Review items. Failed: ${e.failed} Items.`)(t),yr(i)}finally{xn=!1,Sr(),i&&(qr(),await Xa(),yr(`${i} Preview refreshed.`))}}),ht?.addEventListener("click",()=>Za(!0)),mt?.addEventListener("click",()=>Za(!1)),ut?.addEventListener("cancel",e=>{e.preventDefault(),Za(!1)}),ne?.addEventListener("click",jo),G?.addEventListener("click",async()=>{if(!sa())return ir("Select a PlotDirector book first."),void Or("Not detected");Pn&&(window.clearTimeout(Pn),Pn=null),qn=!1,An=!1,xr(!0),br("Updating...");try{await qo(!0);if(!await Qa())return;if(kr(!1),!_t)return await To(),void br("Current scene updated");await jo(),br("Current scene updated")}finally{xr(!1)}}),ge?.addEventListener("click",()=>Eo({source:"manual"})),Pe?.addEventListener("click",async()=>{if(Zt)if(!Ln&&await(async()=>{if(!Zt)return!1;if(!Gt||!Ft||!window.Word||"function"!=typeof window.Word.run)return kr(!0,"The Word cursor is now in a different scene. Refresh Current Scene before saving."),!1;try{const e=await window.Word.run(async e=>await Ya(e)),t=e.currentChapter?.title||"",n=e.currentScene?.title||"",r=e.currentScene?.anchorId||null,a=e.currentChapter?.anchorId||null,o=Number.isInteger(r)&&r===Zt,c=Number.isInteger(a)&&a===en,i=Vr(n,"scene").toLocaleLowerCase()===Vr(Kn||_t,"scene").toLocaleLowerCase(),s=Vr(t,"chapter").toLocaleLowerCase()===Vr(Qn||Yt,"chapter").toLocaleLowerCase();return o||i&&(c||s)?(kr(!1),!0):(kr(!0,"The Word cursor is now in a different scene. Refresh Current Scene before saving."),!1)}catch(e){return console.error("Unable to verify current Word scene before saving.",e),Zr({lastError:ea(e)}),kr(!0,"The Word cursor is now in a different scene. Refresh Current Scene before saving."),!1}})()){Pe&&(Pe.disabled=!0,Pe.textContent="Saving...");try{await(e=`/api/word-companion/scenes/${Zt}/links`,t={characterIds:po(Ee),assetIds:po(Ne),locationIds:[],primaryLocationId:ho()},co(e,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})),(()=>{const e=new Set(po(Ee)),t=new Set(po(Ne));Zn={characters:Zn.characters.map(t=>({...t,linked:e.has(Number.parseInt(Hr(t,"character"),10))})),assets:Zn.assets.map(e=>({...e,linked:t.has(Number.parseInt(Hr(e,"asset"),10))})),locations:Zn.locations,primaryLocationId:ho()}})(),Dr("Scene links saved successfully."),Zr({lastError:"-"})}catch(e){Dr("Unable to save scene links."),Zr({lastError:ea(e)})}finally{Pe&&(Pe.disabled=!Zt||Ln,Pe.textContent="Save Scene Links")}var e,t}else Dr("The Word cursor is now in a different scene. Refresh Current Scene before saving.");else Dr("Link a PlotDirector scene first.")}),se?.addEventListener("click",async()=>{await yo()}),Te?.addEventListener("click",async()=>{const e=sa();if(!e||!Yt||en)return void Rr("Chapter not found in PlotDirector.");const t=Fr(Yt),n=await((e,t)=>(Xr(it,`"${e}"`),Xr(st,`"${t}"`),ct?new Promise(e=>{ln=e,ct.showModal?ct.showModal():ct.hidden=!1}):Promise.resolve(window.confirm(`Create PlotDirector chapter:\n\n"${e}"\n\nin book:\n\n"${t}"\n\n?`))))(t,ca(e)||"selected book");if(n){Te&&(Te.disabled=!0,Te.textContent="Creating...");try{const n=Number.isInteger(Kt)&&Kt>0?10*Kt:null,r=await io(`/api/word-companion/books/${e.bookId}/chapters`,{title:t,sortOrder:n});if(!r?.chapterId)throw new Error("Chapter creation did not return a chapter ID.");qr(),vr(null,r.chapterId,"Manual chapter link");if(!await wo("Chapter created and linked successfully."))return;await fo("Chapter created and linked successfully.")}catch(e){$r("Unable to create chapter."),Zr({lastError:ea(e)})}finally{Te&&(Te.disabled=!Tr(),Te.textContent="Create Chapter in PlotDirector")}}}),je?.addEventListener("click",async()=>{const e=sa();if(e&&Yt&&!en){je&&(je.disabled=!0,je.textContent="Loading...");try{sn=await _r(e.bookId),dn=null,tt&&(tt.value=""),Xr(ot,""),So(),et?.showModal?et.showModal():et&&(et.hidden=!1)}catch(e){$r("Unable to load chapters."),Zr({lastError:ea(e)})}finally{je&&(je.disabled=!Tr(),je.textContent="Link to Existing Chapter")}}else Rr("Chapter not found in PlotDirector.")}),tt?.addEventListener("input",So),rt?.addEventListener("click",async()=>{const e=sn.find(e=>e.chapterId===dn);if(e){rt&&(rt.disabled=!0,rt.textContent="Linking...");try{vr(null,e.chapterId,"Manual chapter link");if(!await wo("Chapter linked successfully."))return;Io(),await fo("Chapter linked successfully.")}catch(e){Xr(ot,"Unable to link chapter."),$r("Unable to link chapter."),Zr({lastError:ea(e)})}finally{rt&&(rt.disabled=!dn,rt.textContent="Link Chapter")}}else Xr(ot,"Select a chapter.")}),at?.addEventListener("click",Io),dt?.addEventListener("click",()=>go(!0)),lt?.addEventListener("click",()=>go(!1)),ct?.addEventListener("cancel",e=>{e.preventDefault(),go(!1)}),Oe?.addEventListener("click",async()=>{const e=sa();if(!e||!_t)return void Mr("Scene not found in PlotDirector.");const t=Vr(_t,"scene"),n=Vr(Yt,"chapter"),r=await((e,t)=>(Xr(Ke,`"${e}"`),Xr(Qe,`"${t}"`),ze?new Promise(e=>{cn=e,ze.showModal?ze.showModal():ze.hidden=!1}):Promise.resolve(window.confirm(`Create PlotDirector scene:\n\n"${e}"\n\nwithin chapter:\n\n"${t}"\n\n?`))))(t,n);if(r){Oe&&(Oe.disabled=!0,Oe.textContent="Creating...");try{const n=await Kr();if(!n)return void Mr("This chapter does not exist in PlotDirector. Create or link the chapter first.");const r=await io(`/api/word-companion/books/${e.bookId}/chapters/${n.chapterId}/scenes`,{sceneTitle:t});if(!r?.sceneId||!r?.chapterId)throw new Error("Scene creation did not return a scene ID.");qr(),await Co(r.sceneId,r.chapterId,"Scene created and linked successfully.")}catch(e){Ar("Unable to create scene."),Zr({lastError:ea(e)})}finally{Oe&&(Oe.disabled=!jr(),Oe.textContent="Create Scene in PlotDirector")}}}),He?.addEventListener("click",async()=>{const e=sa();if(e&&_t){He&&(He.disabled=!0,He.textContent="Loading...");try{const t=await Yr(e.bookId),n=zr(t);if(!n)return void Mr("This chapter does not exist in PlotDirector. Create or link the chapter first.");an=Array.isArray(n.scenes)?n.scenes:[],on=null,Fe&&(Fe.value=""),Xr(_e,""),ko(),Ge?.showModal?Ge.showModal():Ge&&(Ge.hidden=!1)}catch(e){Ar("Unable to load scenes."),Zr({lastError:ea(e)})}finally{He&&(He.disabled=!jr(),He.textContent="Link to Existing Scene")}}else Mr("Scene not found in PlotDirector.")}),Fe?.addEventListener("input",ko),Je?.addEventListener("click",async()=>{const e=sa(),t=an.find(e=>e.sceneId===on);if(e&&t){Je&&(Je.disabled=!0,Je.textContent="Linking...");try{const e=await Kr();if(!e)throw new Error("This chapter does not exist in PlotDirector. Create or link the chapter first.");vo(),await Co(t.sceneId,e.chapterId,"Scene linked successfully.")}catch(e){Xr(_e,"Unable to link scene."),Ar("Unable to link scene."),Zr({lastError:ea(e)})}finally{Je&&(Je.disabled=!on,Je.textContent="Link Scene")}}else Xr(_e,"Select a scene.")}),Ye?.addEventListener("click",vo),Xe?.addEventListener("click",()=>bo(!0)),Ze?.addEventListener("click",()=>bo(!1)),ze?.addEventListener("cancel",e=>{e.preventDefault(),bo(!1)}),Et?.addEventListener("click",async()=>{Et&&(Et.disabled=!0,Et.textContent="Running...");try{if(await ta(),!Gt||!Ft||!window.Word||"function"!=typeof window.Word.run)return void Zr({lastScan:"Failure",lastError:"Word document access is unavailable.",paragraphs:"-",heading1:"-",heading2:"-"});const e=await window.Word.run(async e=>{const t=e.document.body.paragraphs;return t.load("items"),await e.sync(),t.items.length});Zr({lastScan:"Success",lastError:"-",paragraphs:String(e)})}catch(e){console.error("Word Companion diagnostics failed.",e);const t=ea(e);Zr({lastScan:"Failure",lastError:t}),ir(`Unable to scan the Word document: ${t}`)}finally{Et&&(Et.disabled=!1,Et.textContent="Run Diagnostics")}});const Ho=Ot?(async()=>{aa(M,"Loading projects..."),aa(O,"Select a project first"),aa(h,"Loading projects..."),aa(m,"Select a project first"),or(""),cr("");try{const n=await co("/api/word-companion/projects");if(Ht=Array.isArray(n.projects)?n.projects:[],0===Ht.length)return aa(M,"No projects available."),aa(h,"No projects available."),or("No projects available."),ra(e,null),ra(t,null),Ca(),void ya("No projects available.");oa(M,"Choose a project",Ht,"projectId","title"),ma();const r=na(e),a=Ht.find(e=>e.projectId===r);a&&M?(M.value=String(a.projectId),h&&(h.value=String(a.projectId)),ra(e,a.projectId),await Oo(a.projectId,na(t))):(ra(e,null),ra(t,null),Ca(),ya("Select a Project and Book to begin."))}catch{Ht=[],Bt=[],aa(M,"Unable to connect to PlotDirector."),aa(O,"Select a project first"),aa(h,"Unable to connect to PlotDirector."),aa(m,"Select a project first"),ar("Unable to connect to PlotDirector."),or("Unable to connect to PlotDirector."),ra(e,null),ra(t,null),Ca(),ya("Unable to connect to PlotDirector.")}})():Promise.resolve();if(Ot||(aa(M,"Please sign in to PlotDirector."),aa(O,"Please sign in to PlotDirector."),aa(h,"Please sign in to PlotDirector."),aa(m,"Please sign in to PlotDirector."),Ca()),!window.Office||"function"!=typeof window.Office.onReady)return tr("Word Companion ready"),ir("Word document access is unavailable."),br("Manual"),void Zr({host:"Unavailable",platform:"Unavailable",ready:"No",wordApi:"No"});ta().then(async()=>{tr("Word Companion ready"),await Ho,await(async()=>{if(!Ot||!Ft)return void ha(!1);const n=ga();if(n)try{const r=await co(`/api/word-companion/runtime/book/${n.bookId}?documentGuid=${encodeURIComponent(n.documentGuid)}`),a=r?.manuscriptDocument;if(r?.bookId===n.bookId&&r?.projectId===n.projectId&&a&&String(a.documentGuid).toLowerCase()===n.documentGuid.toLowerCase())return pn=n,Lr(r),ra(e,r.projectId),ra(t,r.bookId),M&&(M.value=String(r.projectId)),await Oo(r.projectId,r.bookId),ha(!1),ar("Connected"),cr("Bound manuscript detected."),void await uo()}catch{}pn=null,Pr(),ma(),da()?await Oo(da().projectId,null):aa(m,"Select a project first"),ya("Select a Project and Book to begin."),ha(!0)})(),Ft?(()=>{if(Ot){if(!window.Office?.context?.document||"function"!=typeof window.Office.context.document.addHandlerAsync||!window.Office?.EventType?.DocumentSelectionChanged)return br("Manual"),void ir("Automatic scene tracking is unavailable in this Word version. Use Refresh Current Scene.");try{window.Office.context.document.addHandlerAsync(window.Office.EventType.DocumentSelectionChanged,Uo,e=>{e?.status===window.Office.AsyncResultStatus.Succeeded?(Tn=!0,br("Live")):(br("Manual"),ir("Automatic scene tracking is unavailable in this Word version. Use Refresh Current Scene."))}),window.addEventListener("beforeunload",Mo)}catch(e){console.warn("Unable to register Word selection tracking handler.",e),br("Manual"),ir("Automatic scene tracking is unavailable in this Word version. Use Refresh Current Scene.")}}})():(ir("Word document access is unavailable."),br("Manual"))}).catch(e=>{console.error("Office readiness check failed.",e),ar("Unable to connect to PlotDirector."),tr("Word Companion unavailable"),ir("Word document access is unavailable."),Zr({ready:"No",wordApi:"No",lastScan:"Failure"})})})(); \ No newline at end of file