kward 0.70.0 → 0.72.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/pages.yml +1 -1
  3. data/CHANGELOG.md +89 -3
  4. data/Gemfile +2 -0
  5. data/Gemfile.lock +90 -2
  6. data/README.md +34 -6
  7. data/Rakefile +96 -0
  8. data/doc/agent-tools.md +52 -0
  9. data/doc/api.md +92 -0
  10. data/doc/authentication.md +58 -23
  11. data/doc/code-search.md +42 -2
  12. data/doc/configuration.md +102 -13
  13. data/doc/context-budgeting.md +136 -0
  14. data/doc/context-tools.md +83 -0
  15. data/doc/editor.md +394 -0
  16. data/doc/extensibility.md +16 -7
  17. data/doc/files.md +100 -0
  18. data/doc/getting-started.md +25 -18
  19. data/doc/git.md +122 -0
  20. data/doc/memory.md +24 -4
  21. data/doc/personas.md +34 -5
  22. data/doc/plugins.md +74 -3
  23. data/doc/releasing.md +45 -8
  24. data/doc/rpc.md +77 -15
  25. data/doc/session-management.md +254 -0
  26. data/doc/shell.md +286 -0
  27. data/doc/tabs.md +122 -0
  28. data/doc/troubleshooting.md +77 -1
  29. data/doc/usage.md +60 -15
  30. data/doc/web-search.md +12 -4
  31. data/doc/workspace-tools.md +144 -0
  32. data/examples/plugins/space_invaders.rb +377 -0
  33. data/lib/kward/agent.rb +1 -1
  34. data/lib/kward/cli/commands.rb +41 -2
  35. data/lib/kward/cli/git.rb +150 -0
  36. data/lib/kward/cli/interactive_turn.rb +73 -9
  37. data/lib/kward/cli/openrouter_commands.rb +55 -0
  38. data/lib/kward/cli/plugins.rb +54 -4
  39. data/lib/kward/cli/prompt_interface.rb +111 -6
  40. data/lib/kward/cli/rendering.rb +11 -6
  41. data/lib/kward/cli/runtime_helpers.rb +133 -3
  42. data/lib/kward/cli/sessions.rb +262 -13
  43. data/lib/kward/cli/settings.rb +216 -37
  44. data/lib/kward/cli/slash_commands.rb +439 -8
  45. data/lib/kward/cli/tabs.rb +695 -0
  46. data/lib/kward/cli.rb +171 -26
  47. data/lib/kward/compactor.rb +4 -1
  48. data/lib/kward/config_files.rb +125 -5
  49. data/lib/kward/context_budget_meter.rb +44 -0
  50. data/lib/kward/conversation.rb +59 -22
  51. data/lib/kward/editor_mode.rb +25 -0
  52. data/lib/kward/ekwsh.rb +362 -0
  53. data/lib/kward/model/client.rb +37 -50
  54. data/lib/kward/model/context_usage.rb +13 -6
  55. data/lib/kward/model/model_info.rb +92 -16
  56. data/lib/kward/model/payloads.rb +2 -0
  57. data/lib/kward/openrouter_model_cache.rb +120 -0
  58. data/lib/kward/plugin_registry.rb +108 -1
  59. data/lib/kward/project_files.rb +52 -0
  60. data/lib/kward/prompt_history.rb +82 -0
  61. data/lib/kward/prompt_interface/banner.rb +16 -51
  62. data/lib/kward/prompt_interface/composer_controller.rb +124 -83
  63. data/lib/kward/prompt_interface/composer_renderer.rb +116 -14
  64. data/lib/kward/prompt_interface/composer_state.rb +96 -27
  65. data/lib/kward/prompt_interface/editor/auto_close_pairs.rb +123 -0
  66. data/lib/kward/prompt_interface/editor/auto_indent.rb +509 -0
  67. data/lib/kward/prompt_interface/editor/buffer.rb +109 -0
  68. data/lib/kward/prompt_interface/editor/controller.rb +1018 -0
  69. data/lib/kward/prompt_interface/editor/endwise.rb +321 -0
  70. data/lib/kward/prompt_interface/editor/file_marker.rb +40 -0
  71. data/lib/kward/prompt_interface/editor/indent_navigation.rb +61 -0
  72. data/lib/kward/prompt_interface/editor/kill_ring.rb +78 -0
  73. data/lib/kward/prompt_interface/editor/modes/emacs.rb +259 -0
  74. data/lib/kward/prompt_interface/editor/modes/modern.rb +353 -0
  75. data/lib/kward/prompt_interface/editor/modes/vibe.rb +1962 -0
  76. data/lib/kward/prompt_interface/editor/renderer.rb +243 -0
  77. data/lib/kward/prompt_interface/editor/search.rb +76 -0
  78. data/lib/kward/prompt_interface/editor/selections.rb +120 -0
  79. data/lib/kward/prompt_interface/editor/state.rb +1249 -0
  80. data/lib/kward/prompt_interface/editor/status_text.rb +23 -0
  81. data/lib/kward/prompt_interface/editor/syntax_highlighter.rb +420 -0
  82. data/lib/kward/prompt_interface/editor/undo_history.rb +46 -0
  83. data/lib/kward/prompt_interface/editor/vibe_state.rb +44 -0
  84. data/lib/kward/prompt_interface/file_overlay.rb +211 -0
  85. data/lib/kward/prompt_interface/git_prompt.rb +299 -0
  86. data/lib/kward/prompt_interface/interactive/controller.rb +186 -0
  87. data/lib/kward/prompt_interface/interactive/renderer.rb +71 -0
  88. data/lib/kward/prompt_interface/interactive/state.rb +62 -0
  89. data/lib/kward/prompt_interface/key_handler.rb +416 -43
  90. data/lib/kward/prompt_interface/layout.rb +2 -2
  91. data/lib/kward/prompt_interface/overlay_renderer.rb +21 -2
  92. data/lib/kward/prompt_interface/project_browser.rb +524 -0
  93. data/lib/kward/prompt_interface/prompt_renderer.rb +32 -13
  94. data/lib/kward/prompt_interface/question_prompt.rb +122 -82
  95. data/lib/kward/prompt_interface/runtime_state.rb +49 -1
  96. data/lib/kward/prompt_interface/screen.rb +17 -0
  97. data/lib/kward/prompt_interface/selection_prompt.rb +511 -58
  98. data/lib/kward/prompt_interface/stream_state.rb +7 -0
  99. data/lib/kward/prompt_interface/transcript_buffer.rb +13 -16
  100. data/lib/kward/prompt_interface/transcript_renderer.rb +3 -3
  101. data/lib/kward/prompt_interface.rb +307 -35
  102. data/lib/kward/prompts/commands.rb +7 -1
  103. data/lib/kward/prompts.rb +4 -2
  104. data/lib/kward/rpc/server.rb +45 -11
  105. data/lib/kward/rpc/session_manager.rb +52 -53
  106. data/lib/kward/rpc/session_tree_rows.rb +9 -115
  107. data/lib/kward/rpc/tool_event_normalizer.rb +1 -1
  108. data/lib/kward/session_store.rb +67 -4
  109. data/lib/kward/session_tree_nodes.rb +136 -0
  110. data/lib/kward/session_tree_renderer.rb +9 -131
  111. data/lib/kward/tab_store.rb +47 -0
  112. data/lib/kward/telemetry/logger.rb +5 -3
  113. data/lib/kward/text_boundary.rb +25 -0
  114. data/lib/kward/tool_output_compactor.rb +127 -0
  115. data/lib/kward/tools/base.rb +8 -2
  116. data/lib/kward/tools/context_budget_stats.rb +54 -0
  117. data/lib/kward/tools/context_for_task.rb +202 -0
  118. data/lib/kward/tools/read_file.rb +8 -4
  119. data/lib/kward/tools/registry.rb +92 -15
  120. data/lib/kward/tools/retrieve_tool_output.rb +71 -0
  121. data/lib/kward/tools/search/web.rb +2 -2
  122. data/lib/kward/tools/summarize_file_structure.rb +29 -0
  123. data/lib/kward/tools/tool_call.rb +12 -0
  124. data/lib/kward/version.rb +1 -1
  125. data/lib/kward/workers/git_guard.rb +68 -0
  126. data/lib/kward/workers/live_view.rb +49 -0
  127. data/lib/kward/workers/manager.rb +288 -0
  128. data/lib/kward/workers/store.rb +72 -0
  129. data/lib/kward/workers/tool_policy.rb +23 -0
  130. data/lib/kward/workers/worker.rb +82 -0
  131. data/lib/kward/workers/write_lock.rb +38 -0
  132. data/lib/kward/workers.rb +7 -0
  133. data/lib/kward/workspace.rb +154 -12
  134. data/templates/default/fulldoc/html/css/kward.css +362 -42
  135. data/templates/default/fulldoc/html/full_list.erb +107 -0
  136. data/templates/default/fulldoc/html/js/kward.js +161 -2
  137. data/templates/default/fulldoc/html/setup.rb +8 -0
  138. data/templates/default/kward_navigation.rb +102 -0
  139. data/templates/default/layout/html/layout.erb +43 -10
  140. data/templates/default/layout/html/setup.rb +39 -38
  141. metadata +65 -3
  142. data/lib/kward/resources/avatar_kward_logo.rb +0 -50
  143. data/lib/kward/resources/pixel_logo.rb +0 -232
@@ -10,6 +10,13 @@
10
10
  --kward-accent: #9caf35;
11
11
  --kward-accent-bright: #d2df62;
12
12
  --kward-code: #030604;
13
+ --kward-syntax-comment: #7f8b67;
14
+ --kward-syntax-constant: #f0bf6a;
15
+ --kward-syntax-keyword: #d2df62;
16
+ --kward-syntax-method: #b8d852;
17
+ --kward-syntax-string: #8fd15b;
18
+ --kward-syntax-symbol: #ff7f6f;
19
+ --kward-syntax-variable: #a7c884;
13
20
  }
14
21
 
15
22
  html {
@@ -131,12 +138,31 @@ body.kward-docs::before {
131
138
  width: 1px;
132
139
  }
133
140
 
134
- .kward-guide-search {
141
+ .kward-guide-search,
142
+ .kward-api-index-link {
135
143
  justify-self: end;
144
+ }
145
+
146
+ .kward-guide-search {
136
147
  position: relative;
137
148
  width: min(280px, 24vw);
138
149
  }
139
150
 
151
+ .kward-api-index-link {
152
+ border: 1px solid rgba(156, 175, 53, 0.42);
153
+ border-radius: 999px;
154
+ color: var(--kward-ink);
155
+ padding: 10px 14px;
156
+ text-decoration: none;
157
+ white-space: nowrap;
158
+ }
159
+
160
+ .kward-api-index-link:hover,
161
+ .kward-api-index-link:focus {
162
+ background: rgba(156, 175, 53, 0.13);
163
+ color: var(--kward-accent-bright);
164
+ }
165
+
140
166
  .kward-guide-search input {
141
167
  background: rgba(3, 6, 4, 0.72);
142
168
  border: 1px solid rgba(156, 175, 53, 0.42);
@@ -315,7 +341,41 @@ body.kward-docs a {
315
341
  color: var(--kward-accent-bright);
316
342
  }
317
343
 
318
- body.kward-docs pre {
344
+ body.kward-docs #content quote,
345
+ body.kward-docs #filecontents quote {
346
+ border-left: 3px solid var(--kward-accent);
347
+ color: var(--kward-ink);
348
+ display: block;
349
+ font-style: italic;
350
+ font-size: 18px;
351
+ line-height: 1.8;
352
+ margin: 28px 0;
353
+ padding: 8px 0 8px 46px;
354
+ position: relative;
355
+ }
356
+
357
+ body.kward-docs #content quote::before,
358
+ body.kward-docs #filecontents quote::before {
359
+ color: var(--kward-accent);
360
+ content: "\201C";
361
+ font-family: Georgia, "Times New Roman", serif;
362
+ font-size: 80px;
363
+ font-style: normal;
364
+ left: 4px;
365
+ line-height: 1;
366
+ opacity: 0.55;
367
+ position: absolute;
368
+ top: -10px;
369
+ }
370
+
371
+ body.kward-docs #content quote br,
372
+ body.kward-docs #filecontents quote br {
373
+ content: "";
374
+ display: block;
375
+ margin-bottom: 4px;
376
+ }
377
+
378
+ body.kward-docs #content pre {
319
379
  background: var(--kward-code);
320
380
  border: 1px solid rgba(149, 169, 52, 0.22);
321
381
  border-radius: 10px;
@@ -328,6 +388,90 @@ body.kward-docs code {
328
388
  border-radius: 6px;
329
389
  }
330
390
 
391
+ body.kward-docs pre.code .comment {
392
+ color: var(--kward-syntax-comment);
393
+ font-style: italic;
394
+ }
395
+
396
+ body.kward-docs pre.code .const,
397
+ body.kward-docs pre.code .constant,
398
+ body.kward-docs #content .summary_desc pre.code .const > .object_link a,
399
+ body.kward-docs #content .docstring pre.code .const > .object_link a {
400
+ color: var(--kward-syntax-constant);
401
+ }
402
+
403
+ body.kward-docs pre.code .kw,
404
+ body.kward-docs pre.code .rubyid_require,
405
+ body.kward-docs pre.code .rubyid_extend,
406
+ body.kward-docs pre.code .rubyid_include {
407
+ color: var(--kward-syntax-keyword);
408
+ font-weight: 700;
409
+ }
410
+
411
+ body.kward-docs pre.code .id,
412
+ body.kward-docs #content .summary_desc pre.code .id > .object_link a,
413
+ body.kward-docs #content .docstring pre.code .id > .object_link a {
414
+ color: var(--kward-syntax-method);
415
+ }
416
+
417
+ body.kward-docs pre.code .tstring_content,
418
+ body.kward-docs pre.code .heredoc_beg,
419
+ body.kward-docs pre.code .heredoc_end,
420
+ body.kward-docs pre.code .qwords_beg,
421
+ body.kward-docs pre.code .qwords_end,
422
+ body.kward-docs pre.code .qwords_sep,
423
+ body.kward-docs pre.code .words_beg,
424
+ body.kward-docs pre.code .words_end,
425
+ body.kward-docs pre.code .words_sep,
426
+ body.kward-docs pre.code .qsymbols_beg,
427
+ body.kward-docs pre.code .qsymbols_end,
428
+ body.kward-docs pre.code .qsymbols_sep,
429
+ body.kward-docs pre.code .symbols_beg,
430
+ body.kward-docs pre.code .symbols_end,
431
+ body.kward-docs pre.code .symbols_sep,
432
+ body.kward-docs pre.code .tstring,
433
+ body.kward-docs pre.code .dstring,
434
+ body.kward-docs pre.code .regexp,
435
+ body.kward-docs .dregexp {
436
+ color: var(--kward-syntax-string);
437
+ }
438
+
439
+ body.kward-docs pre.code .label,
440
+ body.kward-docs pre.code .symbol {
441
+ color: var(--kward-syntax-symbol);
442
+ }
443
+
444
+ body.kward-docs pre.code .ivar,
445
+ body.kward-docs pre.code .gvar,
446
+ body.kward-docs pre.code .rubyid_backref,
447
+ body.kward-docs pre.code .rubyid_nth_ref {
448
+ color: var(--kward-syntax-variable);
449
+ }
450
+
451
+ body.kward-docs pre.code .op,
452
+ body.kward-docs pre.code .period,
453
+ body.kward-docs pre.code .comma,
454
+ body.kward-docs pre.code .lparen,
455
+ body.kward-docs pre.code .rparen,
456
+ body.kward-docs pre.code .lbrace,
457
+ body.kward-docs pre.code .rbrace,
458
+ body.kward-docs pre.code .lbracket,
459
+ body.kward-docs pre.code .rbracket {
460
+ color: rgba(239, 232, 208, 0.74);
461
+ }
462
+
463
+ body.kward-docs pre.code a,
464
+ body.kward-docs pre.code a:visited {
465
+ text-decoration-color: rgba(210, 223, 98, 0.45);
466
+ text-decoration-thickness: 1px;
467
+ text-underline-offset: 2px;
468
+ }
469
+
470
+ body.kward-docs pre.code a:hover {
471
+ background: rgba(156, 175, 53, 0.16);
472
+ color: var(--kward-accent-bright);
473
+ }
474
+
331
475
  body.kward-docs .copy-code-button {
332
476
  background: transparent;
333
477
  border: 1px solid rgba(156, 175, 53, 0.48);
@@ -364,7 +508,8 @@ body.kward-docs #footer {
364
508
  }
365
509
 
366
510
  .kward-topnav,
367
- .kward-guide-search {
511
+ .kward-guide-search,
512
+ .kward-api-index-link {
368
513
  display: none;
369
514
  }
370
515
 
@@ -426,11 +571,10 @@ body.kward-docs #footer {
426
571
  }
427
572
 
428
573
  /*
429
- Hero tagline "swosh": "Your terminal." flies out to the left and is
430
- replaced by "Your RPC frontend." flying in from the right, then cycles
431
- back. The second line mirrors it from the opposite side — "Your agent."
432
- flies out to the right and is replaced by "Your engine." flying in from
433
- the left — both lines swap in sync. Pure CSS — no JS. The global
574
+ Hero tagline "swosh": cycles each line through three phrases. The first
575
+ line moves right-to-left: "Your terminal.", "Your RPC frontend.", then
576
+ "Your workflow." The second line mirrors it left-to-right: "Your agent.",
577
+ "Your LLM engine.", then "Your harness." Pure CSS no JS. The global
434
578
  @media (prefers-reduced-motion) rule above collapses the animation to
435
579
  the static original copy ("Your terminal. Your agent.") so it remains
436
580
  accessible and calm.
@@ -455,68 +599,95 @@ body.kward-docs #footer {
455
599
  will-change: transform, opacity;
456
600
  }
457
601
 
458
- /* The longer text ("Your RPC frontend.") stays in flow to size the box;
459
- the shorter "Your terminal." overlays it absolutely. */
460
- .kward-swosh-text-a {
602
+ /* The longest text ("Your RPC frontend.") stays in flow to size the box;
603
+ the shorter phrases overlay it absolutely. */
604
+ .kward-swosh-text-a,
605
+ .kward-swosh-text-e {
461
606
  left: 0.08em;
462
607
  position: absolute;
463
608
  top: 0.16em;
464
609
  }
465
610
 
466
611
  .kward-swosh-text-a {
467
- animation: kward-swosh-a 12s cubic-bezier(0.22, 0.61, 0.36, 1) infinite;
612
+ animation: kward-swosh-a 18s cubic-bezier(0.22, 0.61, 0.36, 1) infinite;
468
613
  }
469
614
 
470
615
  .kward-swosh-text-b {
471
- animation: kward-swosh-b 12s cubic-bezier(0.22, 0.61, 0.36, 1) infinite;
616
+ animation: kward-swosh-b 18s cubic-bezier(0.22, 0.61, 0.36, 1) infinite;
472
617
  position: relative;
473
618
  }
474
619
 
620
+ .kward-swosh-text-e {
621
+ animation: kward-swosh-e 18s cubic-bezier(0.22, 0.61, 0.36, 1) infinite;
622
+ }
623
+
475
624
  @keyframes kward-swosh-a {
476
- 0%, 40% { transform: translateX(0); opacity: 1; filter: none; }
477
- 50% { transform: translateX(-140%); opacity: 0; filter: blur(3px); }
478
- 51%, 88% { transform: translateX(140%); opacity: 0; filter: none; }
625
+ 0%, 25% { transform: translateX(0); opacity: 1; filter: none; }
626
+ 33% { transform: translateX(-140%); opacity: 0; filter: blur(3px); }
627
+ 34%, 92% { transform: translateX(140%); opacity: 0; filter: none; }
479
628
  100% { transform: translateX(0); opacity: 1; filter: none; }
480
629
  }
481
630
 
482
631
  @keyframes kward-swosh-b {
483
- 0%, 40% { transform: translateX(140%); opacity: 0; filter: none; }
484
- 50% { transform: translateX(0); opacity: 1; filter: none; }
485
- 88% { transform: translateX(0); opacity: 1; filter: none; }
632
+ 0%, 25% { transform: translateX(140%); opacity: 0; filter: none; }
633
+ 33% { transform: translateX(0); opacity: 1; filter: none; }
634
+ 58% { transform: translateX(0); opacity: 1; filter: none; }
635
+ 66% { transform: translateX(-140%); opacity: 0; filter: blur(3px); }
636
+ 67%, 100% { transform: translateX(140%); opacity: 0; filter: none; }
637
+ }
638
+
639
+ @keyframes kward-swosh-e {
640
+ 0%, 58% { transform: translateX(140%); opacity: 0; filter: none; }
641
+ 66% { transform: translateX(0); opacity: 1; filter: none; }
642
+ 92% { transform: translateX(0); opacity: 1; filter: none; }
486
643
  100% { transform: translateX(-140%); opacity: 0; filter: blur(3px); }
487
644
  }
488
645
 
489
646
  /*
490
- Second line, mirrored: "Your agent." exits to the right while
491
- "Your LLM engine." enters from the left (left-to-right), in sync with
492
- the first swosh. Both texts keep the accent-bright color of the
493
- original "Your agent." span.
647
+ Second line, mirrored left-to-right. All texts keep the accent-bright
648
+ color of the original "Your agent." span.
494
649
  */
495
- .kward-hero h1 .kward-swosh-text-c {
496
- animation: kward-swosh-c 12s cubic-bezier(0.22, 0.61, 0.36, 1) infinite;
650
+ .kward-hero h1 .kward-swosh-text-c,
651
+ .kward-hero h1 .kward-swosh-text-f {
497
652
  color: var(--kward-accent-bright);
498
653
  left: 0.08em;
499
654
  position: absolute;
500
655
  top: 0.16em;
501
656
  }
502
657
 
658
+ .kward-hero h1 .kward-swosh-text-c {
659
+ animation: kward-swosh-c 18s cubic-bezier(0.22, 0.61, 0.36, 1) infinite;
660
+ }
661
+
503
662
  .kward-hero h1 .kward-swosh-text-d {
504
- animation: kward-swosh-d 12s cubic-bezier(0.22, 0.61, 0.36, 1) infinite;
663
+ animation: kward-swosh-d 18s cubic-bezier(0.22, 0.61, 0.36, 1) infinite;
505
664
  color: var(--kward-accent-bright);
506
665
  position: relative;
507
666
  }
508
667
 
668
+ .kward-hero h1 .kward-swosh-text-f {
669
+ animation: kward-swosh-f 18s cubic-bezier(0.22, 0.61, 0.36, 1) infinite;
670
+ }
671
+
509
672
  @keyframes kward-swosh-c {
510
- 0%, 40% { transform: translateX(0); opacity: 1; filter: none; }
511
- 50% { transform: translateX(140%); opacity: 0; filter: blur(3px); }
512
- 51%, 88% { transform: translateX(-140%); opacity: 0; filter: none; }
673
+ 0%, 25% { transform: translateX(0); opacity: 1; filter: none; }
674
+ 33% { transform: translateX(140%); opacity: 0; filter: blur(3px); }
675
+ 34%, 92% { transform: translateX(-140%); opacity: 0; filter: none; }
513
676
  100% { transform: translateX(0); opacity: 1; filter: none; }
514
677
  }
515
678
 
516
679
  @keyframes kward-swosh-d {
517
- 0%, 40% { transform: translateX(-140%); opacity: 0; filter: none; }
518
- 50% { transform: translateX(0); opacity: 1; filter: none; }
519
- 88% { transform: translateX(0); opacity: 1; filter: none; }
680
+ 0%, 25% { transform: translateX(-140%); opacity: 0; filter: none; }
681
+ 33% { transform: translateX(0); opacity: 1; filter: none; }
682
+ 58% { transform: translateX(0); opacity: 1; filter: none; }
683
+ 66% { transform: translateX(140%); opacity: 0; filter: blur(3px); }
684
+ 67%, 100% { transform: translateX(-140%); opacity: 0; filter: none; }
685
+ }
686
+
687
+ @keyframes kward-swosh-f {
688
+ 0%, 58% { transform: translateX(-140%); opacity: 0; filter: none; }
689
+ 66% { transform: translateX(0); opacity: 1; filter: none; }
690
+ 92% { transform: translateX(0); opacity: 1; filter: none; }
520
691
  100% { transform: translateX(140%); opacity: 0; filter: blur(3px); }
521
692
  }
522
693
 
@@ -1081,17 +1252,26 @@ body.kward-docs .kward-home #footer {
1081
1252
  border-radius: 12px;
1082
1253
  box-shadow: 0 24px 70px rgba(0, 0, 0, 0.48);
1083
1254
  display: none;
1084
- gap: 22px;
1085
- grid-template-columns: repeat(4, minmax(170px, 1fr));
1255
+ gap: 16px;
1256
+ grid-template-columns: repeat(3, minmax(160px, 220px));
1086
1257
  left: 50%;
1258
+ max-width: calc(100vw - 48px);
1087
1259
  opacity: 0;
1088
- padding: 28px 22px 22px;
1260
+ padding: 20px;
1089
1261
  pointer-events: none;
1090
1262
  position: absolute;
1091
1263
  top: 100%;
1092
1264
  transform: translate(-50%, -8px);
1093
1265
  transition: opacity 140ms ease, transform 140ms ease;
1094
- width: min(920px, calc(100vw - 48px));
1266
+ width: max-content;
1267
+ }
1268
+
1269
+ .kward-advanced-nav-dropdown {
1270
+ grid-template-columns: repeat(3, minmax(150px, 200px));
1271
+ }
1272
+
1273
+ .kward-api-nav-dropdown {
1274
+ grid-template-columns: repeat(2, minmax(170px, 210px));
1095
1275
  }
1096
1276
 
1097
1277
  .kward-nav-dropdown::before {
@@ -1257,6 +1437,134 @@ body.kward-docs .kward-home #footer {
1257
1437
  }
1258
1438
  }
1259
1439
 
1440
+ /* YARD's class/method/file list pages use a separate full_list template. */
1441
+ .kward-full-list-body .kward-topbar {
1442
+ position: relative;
1443
+ }
1444
+
1445
+ .kward-full-list-body .kward-page {
1446
+ padding-top: 40px;
1447
+ }
1448
+
1449
+ .kward-full-list-body #content {
1450
+ background: var(--kward-panel-strong);
1451
+ border: 1px solid var(--kward-border);
1452
+ border-radius: 14px;
1453
+ box-shadow: 0 26px 70px rgba(0, 0, 0, 0.28);
1454
+ padding: 38px;
1455
+ }
1456
+
1457
+ .kward-full-list-body .fixed_header {
1458
+ background: transparent;
1459
+ height: auto;
1460
+ margin: 0 0 24px;
1461
+ padding: 0;
1462
+ position: static;
1463
+ width: auto;
1464
+ }
1465
+
1466
+ .kward-full-list-body #full_list_header {
1467
+ color: var(--kward-ink);
1468
+ font-size: clamp(36px, 5vw, 62px);
1469
+ letter-spacing: -0.04em;
1470
+ line-height: 0.98;
1471
+ margin: 0 0 18px;
1472
+ padding: 0;
1473
+ }
1474
+
1475
+ .kward-full-list-body #full_list_nav {
1476
+ color: var(--kward-muted);
1477
+ font-size: 14px;
1478
+ margin: 0 0 18px;
1479
+ }
1480
+
1481
+ .kward-full-list-body #full_list_nav a,
1482
+ .kward-full-list-body #full_list_nav a:visited {
1483
+ color: var(--kward-accent-bright);
1484
+ }
1485
+
1486
+ .kward-full-list-body #full_list_nav a:hover {
1487
+ color: #f0f7a0;
1488
+ }
1489
+
1490
+ .kward-full-list-body #search {
1491
+ color: var(--kward-muted);
1492
+ font-size: 14px;
1493
+ margin: 0;
1494
+ padding: 0;
1495
+ width: auto;
1496
+ }
1497
+
1498
+ .kward-full-list-body #search input {
1499
+ background: rgba(3, 6, 4, 0.72);
1500
+ border: 1px solid rgba(156, 175, 53, 0.42);
1501
+ border-radius: 999px;
1502
+ color: var(--kward-ink);
1503
+ font: inherit;
1504
+ margin-left: 8px;
1505
+ outline: none;
1506
+ padding: 8px 12px;
1507
+ width: min(260px, 60vw);
1508
+ }
1509
+
1510
+ .kward-full-list-body #search input:focus {
1511
+ border-color: var(--kward-accent-bright);
1512
+ box-shadow: 0 0 0 3px rgba(156, 175, 53, 0.18);
1513
+ }
1514
+
1515
+ .kward-full-list-body #full_list {
1516
+ background: rgba(3, 6, 4, 0.42);
1517
+ border: 1px solid rgba(156, 175, 53, 0.22);
1518
+ border-radius: 12px;
1519
+ font-size: 15px;
1520
+ margin: 0;
1521
+ overflow: auto;
1522
+ padding: 8px;
1523
+ }
1524
+
1525
+ .kward-full-list-body #full_list li {
1526
+ color: var(--kward-muted);
1527
+ }
1528
+
1529
+ .kward-full-list-body #full_list li.odd,
1530
+ .kward-full-list-body #full_list li.even {
1531
+ background: transparent;
1532
+ }
1533
+
1534
+ .kward-full-list-body #full_list li .item {
1535
+ border-radius: 8px;
1536
+ padding-bottom: 7px;
1537
+ padding-top: 7px;
1538
+ }
1539
+
1540
+ .kward-full-list-body #full_list .item:hover {
1541
+ background: rgba(156, 175, 53, 0.13);
1542
+ }
1543
+
1544
+ .kward-full-list-body #full_list a,
1545
+ .kward-full-list-body #full_list a:visited {
1546
+ color: var(--kward-ink);
1547
+ }
1548
+
1549
+ .kward-full-list-body #full_list a:hover {
1550
+ color: var(--kward-accent-bright);
1551
+ }
1552
+
1553
+ .kward-full-list-body #full_list li.clicked > .item {
1554
+ background: rgba(156, 175, 53, 0.22);
1555
+ color: var(--kward-ink);
1556
+ }
1557
+
1558
+ .kward-full-list-body #full_list li.clicked > .item a,
1559
+ .kward-full-list-body #full_list li.clicked > .item a:visited {
1560
+ color: var(--kward-accent-bright);
1561
+ }
1562
+
1563
+ .kward-full-list-body #noresults {
1564
+ background: transparent;
1565
+ color: var(--kward-muted);
1566
+ }
1567
+
1260
1568
  /* Pages no longer use YARD's iframe/sidebar layout. */
1261
1569
  .kward-page {
1262
1570
  box-sizing: border-box;
@@ -1301,17 +1609,14 @@ body.kward-docs #main.kward-home {
1301
1609
  justify-content: center;
1302
1610
  }
1303
1611
 
1304
- /* The generated YARD TOC is useful for API pages but too noisy on guide pages. */
1305
- .kward-guide-page #toc {
1306
- display: none;
1307
- }
1612
+ /* The generated YARD TOC is shown on all docs pages. Use the `kward-no-toc` marker to suppress it per page. */
1308
1613
 
1309
1614
 
1310
1615
  /* Code blocks own their copy action. */
1311
1616
  body.kward-docs .code-copy-wrapper {
1617
+ display: flow-root;
1312
1618
  margin: 16px 0 24px;
1313
1619
  position: relative;
1314
- width: 100%;
1315
1620
  }
1316
1621
 
1317
1622
  body.kward-docs .code-copy-wrapper pre,
@@ -1323,11 +1628,14 @@ body.kward-docs .code-copy-wrapper pre.code {
1323
1628
  }
1324
1629
 
1325
1630
  body.kward-docs .code-copy-wrapper .copy-code-button {
1631
+ background: #020503;
1632
+ box-shadow: 0 0 0 4px #020503;
1326
1633
  float: none;
1327
1634
  margin: 0;
1328
1635
  position: absolute;
1329
1636
  right: 12px;
1330
1637
  top: 12px;
1638
+ z-index: 2;
1331
1639
  }
1332
1640
 
1333
1641
 
@@ -1588,8 +1896,9 @@ body.kward-docs #filecontents table {
1588
1896
  border-collapse: collapse;
1589
1897
  color: var(--kward-ink);
1590
1898
  display: block;
1899
+ max-width: 100%;
1591
1900
  overflow-x: auto;
1592
- width: 100%;
1901
+ width: fit-content;
1593
1902
  }
1594
1903
 
1595
1904
  body.kward-docs #content th,
@@ -1737,6 +2046,17 @@ body.kward-docs ul.toplevel a:active {
1737
2046
  color: #000;
1738
2047
  }
1739
2048
 
2049
+ body.kward-docs #content quote,
2050
+ body.kward-docs #filecontents quote {
2051
+ border-left-color: #999;
2052
+ color: #000;
2053
+ }
2054
+
2055
+ body.kward-docs #content quote::before,
2056
+ body.kward-docs #filecontents quote::before {
2057
+ color: #999;
2058
+ }
2059
+
1740
2060
  .kward-page {
1741
2061
  padding: 0;
1742
2062
  max-width: none;
@@ -0,0 +1,107 @@
1
+ <!DOCTYPE html>
2
+ <html <%= "lang=\"#{html_lang}\"" unless html_lang.nil? %>>
3
+ <head>
4
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
5
+ <meta charset="<%= charset %>">
6
+ <% stylesheets_full_list.each do |stylesheet| %>
7
+ <link rel="stylesheet" href="<%= mtime_url(stylesheet) %>" type="text/css" media="screen">
8
+ <% end %>
9
+
10
+ <% javascripts_full_list.each do |javascript| %>
11
+ <script type="text/javascript" charset="utf-8" src="<%= mtime_url(javascript) %>"></script>
12
+ <% end %>
13
+
14
+ <title><%= @list_title %></title>
15
+ <base id="base_target" target="_parent">
16
+ </head>
17
+ <body class="kward-docs kward-content-body kward-full-list-body">
18
+ <a href="#content" class="kward-skip-link">Skip to content</a>
19
+
20
+ <header class="kward-topbar">
21
+ <a class="kward-brand" href="index.html">
22
+ <img class="kward-brand-logo" src="images/kward_logo.png" alt="" aria-hidden="true">
23
+ <span>
24
+ <strong>Kward</strong>
25
+ </span>
26
+ </a>
27
+ <button class="kward-nav-toggle" type="button" aria-expanded="false" aria-controls="kward-primary-nav" aria-label="Toggle navigation menu" onclick="document.body.classList.toggle('kward-nav-open'); this.setAttribute('aria-expanded', document.body.classList.contains('kward-nav-open'))">
28
+ <span class="kward-nav-toggle-bar"></span>
29
+ <span class="kward-nav-toggle-bar"></span>
30
+ <span class="kward-nav-toggle-bar"></span>
31
+ <span class="kward-sr-only">Menu</span>
32
+ </button>
33
+ <nav id="kward-primary-nav" class="kward-topnav" aria-label="Primary navigation">
34
+ <a href="index.html">Home</a>
35
+ <div class="kward-nav-menu">
36
+ <a class="kward-nav-menu-link" href="file.README.html">Guides</a>
37
+ <button class="kward-nav-menu-button" type="button" aria-label="Expand guides" aria-expanded="false">⌄</button>
38
+ <div class="kward-nav-dropdown">
39
+ <% guide_groups.each do |title, items| %>
40
+ <section>
41
+ <h2><%= h title %></h2>
42
+ <% items.each do |label, link| %>
43
+ <a href="<%= url_for(link) %>"><%= h label %></a>
44
+ <% end %>
45
+ </section>
46
+ <% end %>
47
+ </div>
48
+ </div>
49
+ <div class="kward-nav-menu">
50
+ <a class="kward-nav-menu-link" href="file.extensibility.html">Advanced</a>
51
+ <button class="kward-nav-menu-button" type="button" aria-label="Expand advanced guides" aria-expanded="false">⌄</button>
52
+ <div class="kward-nav-dropdown kward-advanced-nav-dropdown">
53
+ <% extension_groups.each do |title, items| %>
54
+ <section>
55
+ <h2><%= h title %></h2>
56
+ <% items.each do |label, link| %>
57
+ <a href="<%= url_for(link) %>"><%= h label %></a>
58
+ <% end %>
59
+ </section>
60
+ <% end %>
61
+ </div>
62
+ </div>
63
+ <div class="kward-nav-menu active">
64
+ <a class="kward-nav-menu-link" href="file.api.html">API Docs</a>
65
+ <button class="kward-nav-menu-button" type="button" aria-label="Expand API docs" aria-expanded="false">⌄</button>
66
+ <div class="kward-nav-dropdown kward-api-nav-dropdown">
67
+ <% api_groups.each do |title, items| %>
68
+ <section>
69
+ <h2><%= h title %></h2>
70
+ <% items.each do |label, link| %>
71
+ <a href="<%= url_for(link) %>"><%= h label %></a>
72
+ <% end %>
73
+ </section>
74
+ <% end %>
75
+ </div>
76
+ </div>
77
+ </nav>
78
+ <a class="kward-api-index-link" href="class_list.html">Search API index</a>
79
+ </header>
80
+
81
+ <main class="kward-page">
82
+ <div id="content" class="kward-content-page kward-api-page">
83
+ <div class="fixed_header">
84
+ <h1 id="full_list_header"><%= @list_title %></h1>
85
+ <div id="full_list_nav">
86
+ <% menu_lists.each do |list| %>
87
+ <span><a target="_self" href="<%= url_for_list list[:type] %>">
88
+ <%= list[:title] %>
89
+ </a></span>
90
+ <% end %>
91
+ </div>
92
+
93
+ <div id="search">
94
+ <label for="search-class">Search:</label>
95
+ <input id="search-class" type="text">
96
+ </div>
97
+ </div>
98
+
99
+ <ul id="full_list" class="<%= @list_class || @list_type %>">
100
+ <%= erb "full_list_#{@list_type}" %>
101
+ </ul>
102
+ </div>
103
+ </main>
104
+
105
+ <script type="text/javascript" charset="utf-8" src="js/kward.js"></script>
106
+ </body>
107
+ </html>