rdoc 7.2.0 → 8.1.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 (150) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +4 -7
  3. data/LICENSE.rdoc +4 -0
  4. data/README.md +43 -2
  5. data/RI.md +75 -75
  6. data/doc/markup_reference/markdown.md +104 -3
  7. data/exe/rdoc +2 -2
  8. data/lib/rdoc/code_object/alias.rb +70 -74
  9. data/lib/rdoc/code_object/any_method.rb +305 -298
  10. data/lib/rdoc/code_object/attr.rb +150 -143
  11. data/lib/rdoc/code_object/class_module.rb +801 -765
  12. data/lib/rdoc/code_object/constant.rb +178 -150
  13. data/lib/rdoc/code_object/context/section.rb +133 -160
  14. data/lib/rdoc/code_object/context.rb +925 -952
  15. data/lib/rdoc/code_object/extend.rb +7 -5
  16. data/lib/rdoc/code_object/include.rb +7 -5
  17. data/lib/rdoc/code_object/method_attr.rb +325 -324
  18. data/lib/rdoc/code_object/mixin.rb +97 -95
  19. data/lib/rdoc/code_object/normal_class.rb +77 -78
  20. data/lib/rdoc/code_object/normal_module.rb +61 -59
  21. data/lib/rdoc/code_object/require.rb +23 -39
  22. data/lib/rdoc/code_object/single_class.rb +21 -19
  23. data/lib/rdoc/code_object/top_level.rb +212 -213
  24. data/lib/rdoc/code_object.rb +305 -305
  25. data/lib/rdoc/comment.rb +274 -337
  26. data/lib/rdoc/cross_reference.rb +194 -212
  27. data/lib/rdoc/encoding.rb +105 -103
  28. data/lib/rdoc/erb_partial.rb +13 -11
  29. data/lib/rdoc/erbio.rb +29 -27
  30. data/lib/rdoc/generator/aliki.rb +165 -140
  31. data/lib/rdoc/generator/darkfish.rb +647 -631
  32. data/lib/rdoc/generator/json_index.rb +233 -229
  33. data/lib/rdoc/generator/markup.rb +165 -122
  34. data/lib/rdoc/generator/pot/message_extractor.rb +57 -51
  35. data/lib/rdoc/generator/pot/po.rb +52 -51
  36. data/lib/rdoc/generator/pot/po_entry.rb +138 -132
  37. data/lib/rdoc/generator/pot.rb +85 -81
  38. data/lib/rdoc/generator/ri.rb +23 -19
  39. data/lib/rdoc/generator/template/aliki/DESIGN.md +538 -0
  40. data/lib/rdoc/generator/template/aliki/_aside_toc.rhtml +1 -1
  41. data/lib/rdoc/generator/template/aliki/_footer.rhtml +1 -1
  42. data/lib/rdoc/generator/template/aliki/_head.rhtml +11 -11
  43. data/lib/rdoc/generator/template/aliki/_header.rhtml +29 -44
  44. data/lib/rdoc/generator/template/aliki/_sidebar_extends.rhtml +8 -6
  45. data/lib/rdoc/generator/template/aliki/_sidebar_includes.rhtml +8 -6
  46. data/lib/rdoc/generator/template/aliki/_sidebar_installed.rhtml +1 -1
  47. data/lib/rdoc/generator/template/aliki/_sidebar_pages.rhtml +2 -2
  48. data/lib/rdoc/generator/template/aliki/_sidebar_search.rhtml +4 -4
  49. data/lib/rdoc/generator/template/aliki/_sidebar_sections.rhtml +1 -1
  50. data/lib/rdoc/generator/template/aliki/_sidebar_toggle.rhtml +1 -1
  51. data/lib/rdoc/generator/template/aliki/class.rhtml +56 -46
  52. data/lib/rdoc/generator/template/aliki/css/rdoc.css +538 -283
  53. data/lib/rdoc/generator/template/aliki/index.rhtml +1 -1
  54. data/lib/rdoc/generator/template/aliki/js/aliki.js +80 -102
  55. data/lib/rdoc/generator/template/aliki/page.rhtml +1 -1
  56. data/lib/rdoc/generator/template/aliki/servlet_not_found.rhtml +1 -1
  57. data/lib/rdoc/generator/template/aliki/servlet_root.rhtml +2 -2
  58. data/lib/rdoc/generator/template/darkfish/_footer.rhtml +1 -1
  59. data/lib/rdoc/generator/template/darkfish/_sidebar_extends.rhtml +8 -6
  60. data/lib/rdoc/generator/template/darkfish/_sidebar_includes.rhtml +8 -6
  61. data/lib/rdoc/generator/template/darkfish/_sidebar_installed.rhtml +1 -1
  62. data/lib/rdoc/generator/template/darkfish/_sidebar_pages.rhtml +1 -1
  63. data/lib/rdoc/generator/template/darkfish/_sidebar_sections.rhtml +1 -1
  64. data/lib/rdoc/generator/template/darkfish/_sidebar_table_of_contents.rhtml +5 -5
  65. data/lib/rdoc/generator/template/darkfish/class.rhtml +18 -21
  66. data/lib/rdoc/generator/template/darkfish/css/rdoc.css +0 -1
  67. data/lib/rdoc/generator/template/darkfish/table_of_contents.rhtml +3 -3
  68. data/lib/rdoc/generator.rb +48 -46
  69. data/lib/rdoc/i18n/locale.rb +99 -95
  70. data/lib/rdoc/i18n/text.rb +109 -105
  71. data/lib/rdoc/i18n.rb +7 -5
  72. data/lib/rdoc/markdown/byte_runtime.rb +80 -0
  73. data/lib/rdoc/markdown.kpeg +30 -21
  74. data/lib/rdoc/markdown.rb +329 -151
  75. data/lib/rdoc/markup/block_quote.rb +12 -8
  76. data/lib/rdoc/markup/document.rb +127 -123
  77. data/lib/rdoc/markup/formatter.rb +215 -221
  78. data/lib/rdoc/markup/heading.rb +1 -4
  79. data/lib/rdoc/markup/include.rb +33 -29
  80. data/lib/rdoc/markup/indented_paragraph.rb +37 -33
  81. data/lib/rdoc/markup/inline_parser.rb +281 -277
  82. data/lib/rdoc/markup/list.rb +80 -88
  83. data/lib/rdoc/markup/list_item.rb +73 -85
  84. data/lib/rdoc/markup/paragraph.rb +23 -19
  85. data/lib/rdoc/markup/parser.rb +501 -497
  86. data/lib/rdoc/markup/pre_process.rb +284 -305
  87. data/lib/rdoc/markup/raw.rb +2 -2
  88. data/lib/rdoc/markup/rule.rb +16 -12
  89. data/lib/rdoc/markup/to_ansi.rb +143 -139
  90. data/lib/rdoc/markup/to_bs.rb +72 -68
  91. data/lib/rdoc/markup/to_html.rb +600 -493
  92. data/lib/rdoc/markup/to_html_crossref.rb +221 -191
  93. data/lib/rdoc/markup/to_html_snippet.rb +232 -227
  94. data/lib/rdoc/markup/to_joined_paragraph.rb +40 -41
  95. data/lib/rdoc/markup/to_label.rb +63 -59
  96. data/lib/rdoc/markup/to_markdown.rb +212 -208
  97. data/lib/rdoc/markup/to_rdoc.rb +336 -332
  98. data/lib/rdoc/markup/to_table_of_contents.rb +66 -62
  99. data/lib/rdoc/markup/to_test.rb +60 -56
  100. data/lib/rdoc/markup/to_tt_only.rb +83 -86
  101. data/lib/rdoc/markup/verbatim.rb +62 -58
  102. data/lib/rdoc/markup.rb +198 -196
  103. data/lib/rdoc/options.rb +1063 -1076
  104. data/lib/rdoc/parser/c.rb +1039 -1036
  105. data/lib/rdoc/parser/changelog.rb +319 -315
  106. data/lib/rdoc/parser/markdown.rb +17 -13
  107. data/lib/rdoc/parser/rbs.rb +279 -0
  108. data/lib/rdoc/parser/rd.rb +17 -13
  109. data/lib/rdoc/parser/ruby.rb +1231 -2222
  110. data/lib/rdoc/parser/ruby_colorizer.rb +303 -0
  111. data/lib/rdoc/parser/simple.rb +31 -27
  112. data/lib/rdoc/parser/text.rb +12 -8
  113. data/lib/rdoc/parser.rb +230 -221
  114. data/lib/rdoc/rbs_helper.rb +186 -0
  115. data/lib/rdoc/rd/inline.rb +57 -53
  116. data/lib/rdoc/rd.rb +90 -88
  117. data/lib/rdoc/rdoc.rb +547 -366
  118. data/lib/rdoc/ri/driver.rb +1141 -1130
  119. data/lib/rdoc/ri/formatter.rb +7 -3
  120. data/lib/rdoc/ri/paths.rb +140 -136
  121. data/lib/rdoc/ri/servlet.rb +456 -0
  122. data/lib/rdoc/ri/store.rb +4 -2
  123. data/lib/rdoc/ri/task.rb +55 -51
  124. data/lib/rdoc/ri.rb +14 -11
  125. data/lib/rdoc/rubygems_hook.rb +194 -192
  126. data/lib/rdoc/server.rb +462 -0
  127. data/lib/rdoc/stats/normal.rb +46 -42
  128. data/lib/rdoc/stats/quiet.rb +39 -35
  129. data/lib/rdoc/stats/verbose.rb +35 -31
  130. data/lib/rdoc/stats.rb +363 -338
  131. data/lib/rdoc/store.rb +919 -725
  132. data/lib/rdoc/task.rb +260 -255
  133. data/lib/rdoc/text.rb +130 -245
  134. data/lib/rdoc/token_stream.rb +101 -115
  135. data/lib/rdoc/tom_doc.rb +203 -201
  136. data/lib/rdoc/version.rb +1 -1
  137. data/lib/rdoc.rb +35 -7
  138. data/lib/rubygems_plugin.rb +2 -11
  139. data/rdoc-logo.svg +43 -0
  140. data/rdoc.gemspec +6 -4
  141. metadata +36 -20
  142. data/lib/rdoc/code_object/anon_class.rb +0 -10
  143. data/lib/rdoc/code_object/ghost_method.rb +0 -6
  144. data/lib/rdoc/code_object/meta_method.rb +0 -6
  145. data/lib/rdoc/markdown/literals.kpeg +0 -21
  146. data/lib/rdoc/markdown/literals.rb +0 -454
  147. data/lib/rdoc/parser/prism_ruby.rb +0 -1112
  148. data/lib/rdoc/parser/ripper_state_lex.rb +0 -302
  149. data/lib/rdoc/parser/ruby_tools.rb +0 -163
  150. data/lib/rdoc/servlet.rb +0 -452
@@ -0,0 +1,538 @@
1
+ # DESIGN.md
2
+
3
+ Single source of truth for the **Aliki** theme's visual language. The generated
4
+ HTML documentation — served from `localhost` (`rdoc --server`),
5
+ [docs.ruby-lang.org](https://docs.ruby-lang.org), and static GitHub Pages —
6
+ implements what's specified here. The implementation lives in one stylesheet,
7
+ [`css/rdoc.css`](css/rdoc.css). When a value here drifts from that file, **the
8
+ stylesheet is wrong** and should be brought back in line.
9
+
10
+ This document follows the
11
+ [Stitch DESIGN.md format](https://github.com/VoltAgent/awesome-design-md) —
12
+ nine sections covering theme, color, type, components, layout, elevation,
13
+ guardrails, responsive behavior, and an agent quick reference.
14
+
15
+ > Scope: this is the **visual** contract only. It does not cover the generator
16
+ > pipeline, templates, or JS architecture.
17
+
18
+ ---
19
+
20
+ ## 1. Visual Theme & Atmosphere
21
+
22
+ **Personality.** Modern, light, content-first. Aliki is a quiet reading surface
23
+ for Ruby API docs — the documentation is the product, and the chrome recedes.
24
+ It should feel like a well-made developer-docs site, not a framework's default
25
+ output.
26
+
27
+ **Context of use.** Developers read reference docs while coding — scanning for a
28
+ method, a signature, a constant. The job is to find the thing and read it
29
+ comfortably. Reading measure and code legibility matter more than decoration.
30
+
31
+ **Mood.** Calm and neutral with a single decisive accent. Warm "stone" grays
32
+ carry the text hierarchy; one red accent carries identity and wayfinding
33
+ (headings, links-on-hover, active TOC, signature cards). Dark mode is a
34
+ first-class, hand-tuned surface — not an inverted afterthought.
35
+
36
+ **Density.** Comfortable, not cramped. A capped 800 px reading measure, generous
37
+ `--space-12` page padding, and a token-driven spacing rhythm. Every element
38
+ earns its space; there is no decorative chrome.
39
+
40
+ **Anti-references.** What Aliki must **not** look or feel like:
41
+
42
+ - **Not Darkfish** — the predecessor theme it deliberately departs from.
43
+ - **Not corporate** — no heavy, dense doc-portal styling.
44
+ - **Not cluttered** — sidebars and chrome stay quiet; content leads.
45
+
46
+ **References (inferred from the implementation, not externally specified).** The
47
+ system-font stack, GitHub-style heading anchors, and a flat token system place
48
+ Aliki in the family of modern, lightweight developer-doc themes. Treat positive
49
+ references as open — the brand is currently defined by its principles and
50
+ anti-references, not a named lookalike.
51
+
52
+ **Surface contexts.**
53
+
54
+ | Surface | Theme | Atmosphere |
55
+ |----------------------------|----------------------------------------|-------------------------------------------------------------------|
56
+ | Generated docs (static) | Light default · Dark via `data-theme` | The primary reading surface; must work offline / from static hosts |
57
+ | Live server (`--server`) | Same light/dark | Servlet pages (root, 404) use lighter chrome — no header/TOC/footer |
58
+
59
+ Aliki ships a **single brand palette** (red) with explicit **light and dark**
60
+ variants — not a multi-theme system.
61
+
62
+ ## 2. Color Palette & Roles
63
+
64
+ All color is defined as CSS custom properties in
65
+ [`css/rdoc.css`](css/rdoc.css): light tokens in `:root`, dark tokens in a
66
+ `[data-theme="dark"]` override block that re-declares **only** what differs.
67
+ Components reference semantic tokens, never raw hex.
68
+
69
+ ### Semantic roles
70
+
71
+ | Role | Token (`--color-…`) | Meaning |
72
+ |--------------------|----------------------------|--------------------------------------------------|
73
+ | Brand accent | `accent-primary` | Identity + wayfinding (headings, active TOC, sig border) |
74
+ | Accent hover | `accent-hover` | Hover/darker accent |
75
+ | Accent subtle | `accent-subtle` | Tinted accent fills (buttons, focus ring) |
76
+ | Primary text | `text-primary` | Body copy, method names |
77
+ | Secondary text | `text-secondary` | Meta, secondary labels, branch |
78
+ | Tertiary text | `text-tertiary` | Placeholders, snippets, signatures, footer-bottom |
79
+ | Page background | `background-primary` | Main surface |
80
+ | Raised/​sunk bg | `background-secondary` / `-tertiary` | Footer, modal close, hover fills |
81
+ | Borders | `border-subtle` / `-default` / `-emphasis` | Hairlines from quiet → strong |
82
+ | Link | `link-default` / `link-hover` | Body links (default = text color; hover = accent) |
83
+ | Code surface | `code-bg` / `code-border` | `<pre>` / inline `code` |
84
+ | Signature card | `sig-bg` / `sig-border` | Method/attribute header card |
85
+ | Page title kind | `title-kind-border` | Border for the class/module kind badge |
86
+ | Nav | `nav-bg` / `nav-text` | Left sidebar surface + text |
87
+ | Table | `th-background` / `td-background` | Header row + zebra rows |
88
+
89
+ ### Brand palette — red ramp (identity, **fixed**)
90
+
91
+ | Step | Hex | | Step | Hex |
92
+ |------|-----------|-|------|-----------|
93
+ | 50 | `#fdeae9` | | 500 | `#eb544f` |
94
+ | 100 | `#fadad3` | | 600 | `#e62923` ← light accent |
95
+ | 200 | `#f8bfbd` | | 700 | `#b8211c` |
96
+ | 300 | `#f5a9a7` | | 800 | `#8a1915` |
97
+ | 400 | `#f07f7b` | | 900 | `#5c100e` |
98
+
99
+ Light accent = `primary-600` (`#e62923`); dark accent = `primary-500`
100
+ (`#eb544f`). **The hue is a fixed brand identity — do not retune it without
101
+ approval** (see §7).
102
+
103
+ ### Neutral palette — warm "stone" ramp
104
+
105
+ `50 #fafaf9 · 100 #f5f5f4 · 200 #e7e5e4 · 300 #d6d3d1 · 400 #a8a29e · 500 #78716c · 600 #57534e · 700 #44403c · 800 #292524 · 900 #1c1917`
106
+
107
+ ### Semantic tokens — resolved values
108
+
109
+ | Role | Light | Dark |
110
+ |-----------------------|---------------------------|---------------------------|
111
+ | `text-primary` | `#1c1917` (neutral-900) | `#fafaf9` (neutral-50) |
112
+ | `text-secondary` | `#57534e` (neutral-600) | `#e7e5e4` (neutral-200) |
113
+ | `text-tertiary` | `#78716c` (neutral-500) | `#a8a29e` (neutral-400) |
114
+ | `background-primary` | `#ffffff` | `#1c1917` (neutral-900) |
115
+ | `background-secondary`| `#fafaf9` (neutral-50) | `#292524` (neutral-800) |
116
+ | `background-tertiary` | `#f5f5f4` (neutral-100) | `#44403c` (neutral-700) |
117
+ | `border-subtle` | `#e7e5e4` (neutral-200) | `#44403c` (neutral-700) |
118
+ | `border-default` | `#d6d3d1` (neutral-300) | `#57534e` (neutral-600) |
119
+ | `border-emphasis` | `#a8a29e` (neutral-400) | `#d6d3d1` (neutral-300) |
120
+ | `link-default` | `#1c1917` | `#fafaf9` |
121
+ | `link-hover` | `#e62923` (primary-600) | `#eb544f` (primary-500) |
122
+ | `accent-primary` | `#e62923` (primary-600) | `#eb544f` (primary-500) |
123
+ | `accent-hover` | `#b8211c` (primary-700) | `#f07f7b` (primary-400) |
124
+ | `accent-subtle` | `#fdeae9` (primary-50) | `rgb(235 84 79 / 10%)` |
125
+ | `title-kind-border` | `#f8bfbd` (primary-200) | `rgb(235 84 79 / 35%)` |
126
+ | `code-bg` | `#f6f8fa` | `#292524` (neutral-800) |
127
+ | `code-border` | `#d6d3d1` | `#44403c` (neutral-700) |
128
+ | `sig-bg` | `#f5f5f4` (neutral-100) | `#211f1e` (hand-picked) |
129
+ | `sig-border` | `#d6d3d1` (neutral-300) | `#44403c` (neutral-700) |
130
+ | `nav-bg` / `nav-text` | `#ffffff` / `#44403c` | `#1c1917` / `#fafaf9` |
131
+
132
+ ### Syntax-highlight palette (`--code-*`)
133
+
134
+ One palette shared across **Ruby, C, and Shell** highlighting. Brighter in dark
135
+ mode so tokens stay legible on the dark code surface.
136
+
137
+ | Token | Light | Dark |
138
+ |---------|-----------|-----------|
139
+ | blue | `#1d4ed8` | `#93c5fd` |
140
+ | green | `#047857` | `#34d399` |
141
+ | orange | `#d97706` | `#fbbf24` |
142
+ | purple | `#7e22ce` | `#c084fc` |
143
+ | red | `#dc2626` | `#f87171` |
144
+ | cyan | `#0891b2` | `#22d3ee` |
145
+ | gray | `#78716c` | `#a8a29e` |
146
+
147
+ ### Search-type badge colors
148
+
149
+ | Type | Light bg / text | Dark bg / text |
150
+ |----------|-----------------------|-----------------------|
151
+ | class | `#e6f0ff` / `#0050a0` | `#1e3a5f` / `#93c5fd` |
152
+ | module | `#e6ffe6` / `#006600` | `#14532d` / `#86efac` |
153
+ | constant | `#fff0e6` / `#995200` | `#451a03` / `#fcd34d` |
154
+ | method | `#f0e6ff` / `#5200a0` | `#3b0764` / `#d8b4fe` |
155
+
156
+ ### Theme-agnostic tokens (not overridden in dark)
157
+
158
+ | Token | Value | Use |
159
+ |------------------------|--------------------------|----------------------------------|
160
+ | `overlay` | `rgb(0 0 0 / 50%)` | Modal / mobile-nav backdrop |
161
+ | `emphasis-bg` | `rgb(255 111 97 / 10%)` | `strong` / `em` highlight |
162
+ | `emphasis-decoration` | `rgb(52 48 64 / 25%)` | `em` dotted underline |
163
+ | `search-highlight-bg` | `rgb(224 108 117 / 10%)` | Matched-term highlight |
164
+ | `success-bg` | `rgb(34 197 94 / 10%)` | Copy-button "copied" state |
165
+
166
+ ### Success palette
167
+ `green-400 #4ade80 · green-500 #22c55e · green-600 #16a34a` — copy-button feedback only.
168
+
169
+ ## 3. Typography Rules
170
+
171
+ ### Font stacks
172
+
173
+ | Family | Stack |
174
+ |--------|------------------------------------------------------------------------------------------------|
175
+ | Sans (base + headings) | `-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif` |
176
+ | Mono | `ui-monospace, 'SFMono-Regular', 'SF Mono', Menlo, Consolas, 'Liberation Mono', monospace` |
177
+
178
+ System fonts only — **no web fonts are shipped** (keeps output lightweight; see
179
+ §7). Headings reuse the base sans; mono is used for code, method headings, and
180
+ type signatures.
181
+
182
+ ### Type scale
183
+
184
+ | Token | rem | px | Token | rem | px |
185
+ |---------|----------|----|---------|----------|----|
186
+ | `xs` | 0.75 | 12 | `2xl` | 1.5 | 24 |
187
+ | `sm` | 0.875 | 14 | `3xl` | 1.875 | 30 |
188
+ | `base` | 1 | 16 | `4xl` | 2.25 | 36 |
189
+ | `lg` | 1.125 | 18 | `5xl` | 3 | 48 |
190
+ | `xl` | 1.25 | 20 | | | |
191
+
192
+ Weights: `normal 400 · medium 500 · semibold 600 · bold 700`.
193
+ Line heights: `tight 1.25 · normal 1.5 · relaxed 1.625` (body is relaxed).
194
+
195
+ ### Heading ladder (`main`)
196
+
197
+ | Element | Size | Weight | Notes |
198
+ |---------|------------|-----------|-----------------------------------------|
199
+ | `h1.page-title` | kind badge: `sm` / name: `3xl` (30) | semibold / bold | Type kind renders as an accent badge above the class/module name; long names may wrap |
200
+ | `h1` | `3xl` (30) | bold | tight line-height |
201
+ | `h2` | `2xl` (24) | semibold | `margin-top: space-8`; section headers add a 1 px top rule + `space-3` padding |
202
+ | `h3` | `xl` (20) | semibold | `margin-top: space-8`; section headers add a 1 px top rule + `space-3` padding |
203
+ | `h4` | `lg` (18) | medium | |
204
+ | `h5`/`h6` | `base` (16) | medium | |
205
+
206
+ All headings render in `accent-primary` and carry
207
+ `scroll-margin-top: calc(header-height + 2rem)` so anchored links clear the
208
+ sticky header.
209
+
210
+ ### Color × text pairing
211
+
212
+ - Body links default to **text color**, not accent — only hover reveals accent
213
+ (`link-hover`). Keeps prose calm.
214
+ - Status/role meaning in search badges is carried by **both** a tinted
215
+ background and a text color, never color alone.
216
+ - `strong` and `em` share the accent color + `emphasis-bg` tint; `em` adds a
217
+ dotted underline so emphasis survives in monochrome.
218
+
219
+ ## 4. Component Stylings
220
+
221
+ Spacing/radius tokens referenced below resolve in §5/§6.
222
+
223
+ ### Header bar (`header.top-navbar`)
224
+
225
+ | Property | Value |
226
+ |------------|-------------------------------------------------------------|
227
+ | Layout | Sticky top, `z-fixed` (300), `height: 64px`; desktop grid mirrors the page shell so search aligns to the main content rail |
228
+ | Background | `background-primary` + `border-bottom` hairline + `shadow-sm` |
229
+ | Padding | Desktop columns are unpadded; brand/toggle use `space-6` side offsets, search rail uses main content `space-8` inset (mobile header: `space-4`) |
230
+ | Brand | `xl` (20) semibold; hover → accent |
231
+ | Search | content-rail aligned desktop field, `width: 400px` within the main rail (see Search below) |
232
+
233
+ ### Theme toggle (`.theme-toggle`)
234
+
235
+ | Property | Value |
236
+ |----------|------------------------------------------------------------------|
237
+ | Box | `2.5rem` square · `radius-md` · 1px `border-default` |
238
+ | Hover | `background-secondary`, accent border + text, `scale(1.05)` |
239
+ | Active | `scale(0.95)` |
240
+ | Focus | accent border + `0 0 0 3px accent-subtle` ring |
241
+ | Icon | rotates `15deg` + `scale(1.1)` on hover, `--ease-out-smooth` |
242
+
243
+ ### Left navigation (`#sidebar-navigation` + `.nav-section`)
244
+
245
+ | Property | Value |
246
+ |-----------------|--------------------------------------------------------------|
247
+ | Surface | `nav-bg`, `border-right` hairline, sticky under header, full-height scroll; rules are scoped to `#sidebar-navigation` so the right TOC can use its own `<nav>` semantics |
248
+ | Scrollbar | 6 px, `border-default` thumb (custom, thin) |
249
+ | Section heading | `lg` semibold in **accent**, `border-bottom` |
250
+ | Section padding | `margin-top: space-6`, `padding: 0 space-6` |
251
+ | Link hover | `padding-left: space-1` nudge + `link-hover` color + underline |
252
+ | Collapsible | `<details>` with `::details-content` `block-size` 200 ms ease + `interpolate-size: allow-keywords` |
253
+ | Section icon | `1.25rem`, accent color · chevron `1rem`, tertiary, rotates `90deg` open |
254
+ | Nested list | `border-left` subtle hairline, `margin-left: 9px` (aligns to icon center) |
255
+
256
+ ### Signature card (`.method-header` / `.method-heading`)
257
+
258
+ The defining content component — a method or attribute presented as a card.
259
+
260
+ | Property | Value |
261
+ |-----------------|--------------------------------------------------------------|
262
+ | Card | `sig-bg` background · 1px `sig-border` full border · `radius-md` |
263
+ | Layout | two-column grid, `minmax(0, 1fr) auto`, `gap: space-4`; narrows to one column on `≤480px` |
264
+ | Padding | `space-4` desktop, `space-2` on `≤480px` |
265
+ | Heading group | `.method-heading-group`, `min-width: 0`; contains method heading(s) and optional method type signature |
266
+ | Heading | flex column, **mono**, `lg`, semibold; name `overflow-wrap: anywhere` |
267
+ | Type signature (method) | `pre.method-type-signature` — transparent, dotted top rule via `::before`, `sm` mono, `text-tertiary`, tight, `pre-wrap` |
268
+ | Type signature (attribute) | inline after `[RW]` badge, `sm` mono, `text-secondary` |
269
+ | Source toggle (`.method-controls summary`) | static grid action inside the card header; inline-flex with `{}` `.method-source-icon`, accent text on `accent-subtle`, `radius-sm`, `sm` medium; hover `primary-100` bg + `primary-300` border + `translateY(-1px)`; active `scale(0.96)` |
270
+ | Source reveal | `.method-source-code` animates `max-height`+`opacity`+`translateY`, `--duration-medium`/`-fast` + `--ease-out-smooth`; revealed `<pre>` uses the standard code border |
271
+ | `:target` | method-detail gets a neutral left-rail indent treatment |
272
+
273
+ ### Code (`pre`, `code`) + copy button
274
+
275
+ | Property | Value |
276
+ |---------------|----------------------------------------------------------------|
277
+ | `pre` | mono, `code-bg`, 1px `code-border`, `radius-md`, `space-4` pad, `sm`, `x-scroll` |
278
+ | inline `code` | `code-bg`, 1px `border-subtle`, `0.125rem 0.375rem` pad, `radius-sm`, `0.9em` |
279
+ | Copy button | absolute top/right `space-2`, `2rem` square, `radius-sm`, opacity `0.6` |
280
+ | Copy hover | opacity `1`, `background-tertiary`, `translateY(-1px)`, `shadow-md` |
281
+ | Copy active | `scale(0.92)` |
282
+ | Copied | `success-bg` + green-500 border + green-600 check (green-400 in dark) |
283
+
284
+ ### Tables
285
+
286
+ `th`/`td` padding `0.2em 0.4em`, 1px `border-default`; `th` uses
287
+ `th-background`; even rows use `td-background`. On `≤480px` tables scroll
288
+ horizontally.
289
+
290
+ ### Search
291
+
292
+ One search form and one result list serve both header layouts. CSS changes the presentation at `1023px`.
293
+
294
+ | Element | Value |
295
+ |----------------------------------|-------------------------------------------------------------|
296
+ | Shared field (`#search-field`) | full-width border-box, `space-2 space-4` pad, 1px border, `radius-md`, `base`. Focus uses an accent border + `0 0 0 3px accent-subtle` |
297
+ | Desktop results (`#search-results`) | absolute inside the search surface, full-width border-box, `max-height: 60vh`, `radius-lg`, `shadow-lg`, `z-popover` (500) |
298
+ | Compact surface (`.navbar-search.is-open .search-surface`) | centered overlay, `max-width: 600px`, `max-height: 80vh`, `radius-lg`, `shadow-xl` |
299
+ | Compact result item | `space-3 space-4` pad, `radius-md`, hover `background-secondary` |
300
+ | Servlet field | pill `border-radius: 1.25rem`, leading 🔍 (`\1F50D`) glyph |
301
+ | Result lines | `.search-match` `base` · `.search-namespace` `sm` secondary · `.search-snippet` `sm` tertiary |
302
+ | Type badge (`.search-type-*`) | inline-block, `space-0 space-2` pad, `xs`, weight 500, `radius-sm`, colors per §2 |
303
+ | Matched term (`li em`) | `search-highlight-bg`, `font-style: normal` |
304
+
305
+ ### Right TOC (`#table-of-contents`)
306
+
307
+ | Property | Value |
308
+ |---------------|----------------------------------------------------------------|
309
+ | Layout | sticky under header, `padding: space-8 space-6`, `border-left` hairline; its internal `.toc-nav` owns its scroll area and does not inherit left-navigation chrome |
310
+ | Heading | `lg` semibold, `text-primary` |
311
+ | Indent | `.toc-h2` `margin-left: space-4`, `.toc-h3` `space-8`; nested `ul` border-left + `space-4` pad |
312
+ | Link | block, `text-secondary`; hover `link-hover` + underline; focus-visible accent outline |
313
+ | **Active (scroll-spy)** | `accent-primary` + `font-weight: medium` |
314
+ | Visibility | hidden `≤1279px` |
315
+
316
+ ### Footer (`footer.site-footer`) + breadcrumb
317
+
318
+ Footer: `background-secondary`, `border-top`, `padding: space-12 space-6`;
319
+ columns via `repeat(auto-fit, minmax(200px, 1fr))`, gap `space-8`; column `h3`
320
+ is `sm` semibold with `letter-spacing: 0.05em`; `.footer-bottom` is centered
321
+ `xs` `text-tertiary` credit. Breadcrumb (`ol.breadcrumb`) is a wrapping flex row
322
+ at `125%` font-size; long namespace parts may wrap on narrow screens.
323
+
324
+ ## 5. Layout Principles
325
+
326
+ ### Spacing scale (`--space-*`)
327
+
328
+ ```
329
+ 1 · 2 · 3 · 4 · 5 · 6 · 8 · 12 · 16 (4 · 8 · 12 · 16 · 20 · 24 · 32 · 48 · 64 px)
330
+ ```
331
+
332
+ Non-linear above `6` — there is no `7`/`9`/`10`/`11`. Anything outside this list
333
+ is suspect; reach for the nearest token.
334
+
335
+ ### Page grid (`body`)
336
+
337
+ | Mode | Grid |
338
+ |--------------------|----------------------------------------------------------------|
339
+ | Default (2-col) | areas `header / "nav main" / "nav footer"`; columns `300px 1fr` |
340
+ | `.has-toc` (3-col) | adds a TOC column `minmax(240px, 18%)` |
341
+ | `≤1023px` | collapses to `flex` column; nav becomes an off-canvas drawer |
342
+
343
+ Key layout tokens: `sidebar-width 300px · content-max-width 800px ·
344
+ header-height 64px · search-width 400px · toc-width minmax(240px, 18%)`.
345
+
346
+ ### Reading measure & density
347
+
348
+ `main` is capped at **800 px** and centered, with `space-12 space-8` (48 / 32 px)
349
+ padding, `min-width: 0` inside the page grid, and `relaxed` (1.625) line-height
350
+ — a comfortable column for prose and signatures. The left nav and right TOC are
351
+ sticky and independently scrollable, so the reading column never jumps.
352
+
353
+ ### Alignment
354
+
355
+ - Content + nav + TOC: leading-aligned.
356
+ - Method source toggle: static trailing action inside the signature card grid.
357
+ - Centered text is reserved for empty states and the footer credit.
358
+
359
+ ## 6. Depth & Elevation
360
+
361
+ Hierarchy comes from **hairline borders, surface tinting, and a restrained
362
+ shadow set** — used together. (Unlike some flat systems, Aliki *does* use
363
+ shadows, but only for genuinely floating surfaces.)
364
+
365
+ ### Radius scale
366
+
367
+ | Radius | Usage |
368
+ |-------------------|----------------------------------------------------------|
369
+ | `sm` (4 px) | inline code, badges, copy button, source-toggle, chips |
370
+ | `md` (6 px) | `pre`, header controls, theme toggle, search field, modal (small screens) |
371
+ | `lg` (8 px) | search dropdown, search modal content |
372
+ | `1.25rem` (20 px) | servlet search field (pill) |
373
+
374
+ ### Shadow scale
375
+
376
+ | Token | Light (`rgb(0 0 0 / 10%)`) | Dark (40% opacity) | Used by |
377
+ |-------|--------------------------------------------|--------------------|------------------------|
378
+ | `sm` | `0 1px 3px`, `0 1px 2px -1px` | same geometry | header bar |
379
+ | `md` | `0 2px 8px` | same | copy-button hover |
380
+ | `lg` | `0 10px 15px -3px`, `0 4px 6px -4px` | same | nav drawer, search dropdown |
381
+ | `xl` | `0 20px 25px -5px`, `0 8px 10px -6px` | same | search modal |
382
+
383
+ ### Borders & focus
384
+
385
+ - Three hairline weights: `border-subtle` → `border-default` → `border-emphasis`.
386
+ The 1 px hairline is the primary divider everywhere (nav, header, cards, table).
387
+ - **Focus ring:** `box-shadow: 0 0 0 3px accent-subtle` on interactive controls
388
+ (theme toggle, search field, copy button) paired with an accent border.
389
+
390
+ ### Motion
391
+
392
+ | Token | Value | Where |
393
+ |-------------------|-----------------------------|----------------------------------------|
394
+ | `transition-fast` | `150ms ease-in-out` | color/background hovers |
395
+ | `transition-base` | `200ms ease-in-out` | links, chevron rotation |
396
+ | `transition-slow` | `350ms ease-in-out` | — |
397
+ | `ease-out-smooth` | `cubic-bezier(0.4, 0, 0.2, 1)` | theme-toggle icon, source reveal |
398
+ | `duration-fast/​base/​medium` | `250 / 300 / 350ms` | source-code reveal, theme icon |
399
+
400
+ Z-index ladder: `fixed 300 · modal 400 · popover 500`.
401
+
402
+ ## 7. Do's and Don'ts
403
+
404
+ ### Load-bearing guardrails
405
+
406
+ 1. **The red is fixed identity.** Reskin via other tokens freely, but **do not
407
+ change the `--color-primary-*` hue without approval** — it cascades across
408
+ headings, links, active TOC, signature borders, and badges.
409
+ 2. **Never break static / offline viewing.** Output must render with no server
410
+ on GitHub Pages and `file://`. Don't introduce anything that needs a backend
411
+ or a same-origin `fetch()`.
412
+ 3. **Accessibility bar = WCAG 2.1 AA + honor `prefers-reduced-motion`.** Treat
413
+ gaps as bugs. ⚠️ **`prefers-reduced-motion` is not yet implemented** (nav
414
+ collapse, TOC scroll, source-reveal, and `::details-content` all animate
415
+ unconditionally) — adding a reduced-motion block is the top open item (§8).
416
+ 4. **Edit light *and* dark together.** Any new color/semantic token must be
417
+ declared in both `:root` and `[data-theme="dark"]`.
418
+ 5. **Change tokens, not literals.** Components must reference `--*` tokens.
419
+
420
+ ### Do / Don't
421
+
422
+ | Don't | Do |
423
+ |-----------------------------------------------------|-----------------------------------------------------------|
424
+ | Retune the brand red | Reskin via neutrals / semantic tokens; keep the red hue |
425
+ | Hard-code hex in a component rule | Reference a semantic token (`accent-primary`, `text-…`) |
426
+ | Add a color in `:root` only | Add it to the `[data-theme="dark"]` block too |
427
+ | Use `prefers-color-scheme` for dark | Key off the `[data-theme="dark"]` attribute (JS-set) |
428
+ | Add a syntax token class without CSS | Add `.{ruby,c,sh}-*` rule **and** the emitter together |
429
+ | Ship a web font or image sprite | Stay on the system font stack; inline SVG only |
430
+ | Invent a 6th syntax color | Map onto the existing `--code-*` seven |
431
+ | Animate with no reduced-motion guard | Wrap non-essential motion in `prefers-reduced-motion` |
432
+ | Convey meaning by color alone | Pair color with text/weight (badges, emphasis) |
433
+ | Add decorative shadows | Use the `sm/md/lg/xl` set only for truly floating surfaces |
434
+
435
+ ## 8. Responsive Behavior
436
+
437
+ The generated docs are fluid; the layout adapts at five breakpoints.
438
+
439
+ | Breakpoint | Behavior |
440
+ |-----------------------|--------------------------------------------------------------------------------------------|
441
+ | `1024–1279px` | Right **TOC hidden**; `.has-toc` grid drops to 2 columns while the footer stays in the content column |
442
+ | `≤1023px` | Right **TOC hidden**; body → flex column; **left nav becomes an off-canvas drawer** (`300px`, `shadow-lg`) with an `overlay` backdrop + hamburger (`#sidebar-navigation-toggle`); desktop search swaps to a mobile **search modal**; header padding/gap tighten to `space-4` |
443
+ | `768–1023px` (tablet) | Header `0 space-6`; main `space-8 space-6`, full-width |
444
+ | `≤480px` | Nav `width: 85%` (max `320px`); main padding `space-4`; tables scroll; method heading → `base`; signature card padding tightens |
445
+ | `≤420px` | Search modal padding tightens |
446
+ | `(hover: none)` | Copy button rests at opacity `0.7` |
447
+
448
+ ### Color scheme
449
+
450
+ Dark mode is the **`[data-theme="dark"]` attribute** on the document root, set by
451
+ `theme-toggle.js` and persisted in `localStorage` (`rdoc-theme`). It is **not**
452
+ driven by `prefers-color-scheme`. Light is the default.
453
+
454
+ ### Reduced motion ⚠️ (target, not yet implemented)
455
+
456
+ The standard: under `prefers-reduced-motion: reduce`, all non-essential
457
+ transitions/animations should collapse to instant — the nav-section
458
+ `::details-content` block-size tween, the method-source-code reveal, the
459
+ theme-toggle icon spin, chevron rotations, and any smooth-scroll. This guard
460
+ does not exist yet and should be added to satisfy the AA + reduced-motion bar.
461
+
462
+ ## 9. Agent Prompt Guide
463
+
464
+ A cheat-sheet for prompting AI tools (or new contributors) to produce
465
+ Aliki-consistent UI.
466
+
467
+ ### One-line palette identifier
468
+
469
+ | Mode | accent | bg | fg | accent-hover |
470
+ |-------|-----------|-----------|-----------|--------------|
471
+ | Light | `#e62923` | `#ffffff` | `#1c1917` | `#b8211c` |
472
+ | Dark | `#eb544f` | `#1c1917` | `#fafaf9` | `#f07f7b` |
473
+
474
+ Neutral ramp (warm stone): `#fafaf9 #f5f5f4 #e7e5e4 #d6d3d1 #a8a29e #78716c #57534e #44403c #292524 #1c1917`.
475
+
476
+ ### Syntax colors (light → dark)
477
+
478
+ ```
479
+ blue #1d4ed8 → #93c5fd purple #7e22ce → #c084fc
480
+ green #047857 → #34d399 red #dc2626 → #f87171
481
+ orange #d97706 → #fbbf24 cyan #0891b2 → #22d3ee
482
+ gray #78716c → #a8a29e
483
+ ```
484
+
485
+ ### Font stacks
486
+
487
+ ```
488
+ Sans/Headings: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, … sans-serif
489
+ Mono: ui-monospace, 'SFMono-Regular', 'SF Mono', Menlo, Consolas, … monospace
490
+ (no web fonts — system stacks only)
491
+ ```
492
+
493
+ ### Ladders
494
+
495
+ ```
496
+ Type: 12 · 14 · 16 · 18 · 20 · 24 · 30 · 36 · 48 (xs…5xl)
497
+ Spacing: 4 · 8 · 12 · 16 · 20 · 24 · 32 · 48 · 64 (space-1…16)
498
+ Radius: 4 · 6 · 8 (+ 20px servlet pill)
499
+ Layout: sidebar 300 · content 800 · header 64 · search 400 · toc minmax(240, 18%)
500
+ ```
501
+
502
+ ### Ready-to-use prompt fragments
503
+
504
+ > "Use the Aliki theme: red accent `#e62923` (light) / `#eb544f` (dark), warm
505
+ > stone neutrals, page bg `#fff` / `#1c1917`, text `#1c1917` / `#fafaf9`. Body
506
+ > links are text-colored and only turn red on hover. Dark mode keys off a
507
+ > `[data-theme="dark"]` attribute, not `prefers-color-scheme`."
508
+
509
+ > "Layout: 2-column (300 px nav + 800 px content), optional 3rd TOC column
510
+ > `minmax(240px, 18%)`; 64 px sticky header. Spacing scale
511
+ > 4/8/12/16/20/24/32/48/64; radii 4/6/8. Hairline 1 px borders + a restrained
512
+ > sm/md/lg/xl shadow set for floating surfaces only."
513
+
514
+ > "Type: system sans for everything, mono for code + method headings + RBS
515
+ > signatures. Heading ladder h1 30 / h2 24 / h3 20, all in the red accent.
516
+ > Class/module page titles render the kind as a small accent badge above the
517
+ > red `3xl` object name.
518
+ > Comfortable density, 1.625 body line-height. No web fonts, no image sprites."
519
+
520
+ > "Don't retune the red hue, don't hard-code hex (use `--color-*` tokens), don't
521
+ > add a token to `:root` without the dark block, and wrap any new animation in a
522
+ > `prefers-reduced-motion` guard."
523
+
524
+ ### Where to look in `css/rdoc.css`
525
+
526
+ | Asking about… | Read this |
527
+ |----------------------|-----------------------------------------------------------------|
528
+ | Tokens (light) | `:root` — §1 banner "Design System" |
529
+ | Tokens (dark) | `[data-theme="dark"]` block |
530
+ | Layout grid | §2 "Global Styles & Layout" |
531
+ | Code / copy button | §5 "Code and Pre" |
532
+ | Header / theme toggle| §6 "Header (Top Navbar)" |
533
+ | Left nav (`#sidebar-navigation`) | §7 "Navigation (Left Sidebar)" |
534
+ | Signature cards, syntax classes | §8 "Main Content" (syntax classes ~`.ruby/.c/.sh-*`) |
535
+ | Search (modal + dropdown + badges) | §9 "Search Modal" + the `.search-results` block |
536
+ | TOC scroll-spy | §10 "Right Sidebar - Table of Contents" |
537
+ | Footer | §11 "Footer" |
538
+ | Theme attribute / persistence | `js/theme-toggle.js` (`data-theme`, `localStorage`) |
@@ -1,4 +1,4 @@
1
- <aside class="table-of-contents" role="complementary" aria-label="Table of Contents">
1
+ <aside id="table-of-contents" class="table-of-contents" role="complementary" aria-label="Table of Contents">
2
2
  <div class="toc-sticky">
3
3
  <h3 class="toc-heading">On This Page</h3>
4
4
  <nav class="toc-nav" id="toc-nav" aria-label="Page sections">
@@ -16,7 +16,7 @@
16
16
 
17
17
  <div class="footer-bottom">
18
18
  <p>
19
- Generated by <a href="https://ruby.github.io/rdoc/">RDoc <%= RDoc::VERSION %></a>
19
+ Generated by <a href="https://ruby.github.io/rdoc/">RDoc <%= VERSION %></a>
20
20
  using the Aliki theme by <a href="http://st0012.dev">Stan Lo</a>
21
21
  </p>
22
22
  </div>
@@ -28,7 +28,7 @@
28
28
  <%- elsif @title %>
29
29
  <meta name="keywords" content="ruby,documentation,<%= h @title %>">
30
30
  <%- if @options.main_page and
31
- main_page = @files.find { |f| f.full_name == @options.main_page } then %>
31
+ main_page = @files.find { |f| f.full_name == @options.main_page } %>
32
32
  <meta
33
33
  name="description"
34
34
  content="<%= h "#{@title}: #{excerpt(main_page.comment)}" %>"
@@ -112,52 +112,52 @@
112
112
  </script>
113
113
 
114
114
  <script
115
- src="<%= h asset_rel_prefix %>/js/theme-toggle.js?v=<%= h RDoc::VERSION %>"
115
+ src="<%= h asset_rel_prefix %>/js/theme-toggle.js?v=<%= h VERSION %>"
116
116
  ></script>
117
117
 
118
118
  <script
119
- src="<%= h asset_rel_prefix %>/js/search_navigation.js?v=<%= h RDoc::VERSION %>"
119
+ src="<%= h asset_rel_prefix %>/js/search_navigation.js?v=<%= h VERSION %>"
120
120
  defer
121
121
  ></script>
122
122
 
123
123
  <script
124
- src="<%= h asset_rel_prefix %>/js/search_data.js?v=<%= h RDoc::VERSION %>"
124
+ src="<%= h asset_rel_prefix %>/js/search_data.js?v=<%= h VERSION %>"
125
125
  defer
126
126
  ></script>
127
127
 
128
128
  <script
129
- src="<%= h asset_rel_prefix %>/js/search_ranker.js?v=<%= h RDoc::VERSION %>"
129
+ src="<%= h asset_rel_prefix %>/js/search_ranker.js?v=<%= h VERSION %>"
130
130
  defer
131
131
  ></script>
132
132
 
133
133
  <script
134
- src="<%= h asset_rel_prefix %>/js/search_controller.js?v=<%= h RDoc::VERSION %>"
134
+ src="<%= h asset_rel_prefix %>/js/search_controller.js?v=<%= h VERSION %>"
135
135
  defer
136
136
  ></script>
137
137
 
138
138
  <script
139
- src="<%= h asset_rel_prefix %>/js/c_highlighter.js?v=<%= h RDoc::VERSION %>"
139
+ src="<%= h asset_rel_prefix %>/js/c_highlighter.js?v=<%= h VERSION %>"
140
140
  defer
141
141
  ></script>
142
142
 
143
143
  <script
144
- src="<%= h asset_rel_prefix %>/js/bash_highlighter.js?v=<%= h RDoc::VERSION %>"
144
+ src="<%= h asset_rel_prefix %>/js/bash_highlighter.js?v=<%= h VERSION %>"
145
145
  defer
146
146
  ></script>
147
147
 
148
148
  <script
149
- src="<%= h asset_rel_prefix %>/js/aliki.js?v=<%= h RDoc::VERSION %>"
149
+ src="<%= h asset_rel_prefix %>/js/aliki.js?v=<%= h VERSION %>"
150
150
  defer
151
151
  ></script>
152
152
 
153
153
  <link
154
- href="<%= h asset_rel_prefix %>/css/rdoc.css?v=<%= h RDoc::VERSION %>"
154
+ href="<%= h asset_rel_prefix %>/css/rdoc.css?v=<%= h VERSION %>"
155
155
  rel="stylesheet"
156
156
  >
157
157
 
158
158
  <%- @options.template_stylesheets.each do |stylesheet| %>
159
159
  <link
160
- href="<%= h asset_rel_prefix %>/<%= h File.basename stylesheet %>?v=<%= h RDoc::VERSION %>"
160
+ href="<%= h asset_rel_prefix %>/<%= h File.basename stylesheet %>?v=<%= h VERSION %>"
161
161
  rel="stylesheet"
162
162
  >
163
163
  <%- end %>