this repo has no description
at main 529 lines 12 kB view raw
1(** Theme CSS files for the scrollycode extension. 2 3 Each theme sets the CSS custom property values defined in 4 {!Scrollycode_css.structural_css} and imports its Google Fonts. *) 5 6(** Warm Workshop theme. 7 Cream background, burnt sienna accents, Fraunces + Source Serif 4. *) 8let warm_css = 9 {|@import url('https://fonts.googleapis.com/css2?family=Fraunces:ital,opsz,wght@0,9..144,300..900;1,9..144,300..900&family=Source+Code+Pro:ital,wght@0,300..900;1,300..900&family=Source+Serif+4:ital,opsz,wght@0,8..60,300..900;1,8..60,300..900&display=swap'); 10 11.sc-container { 12 /* Typography */ 13 --sc-font-display: 'Fraunces', serif; 14 --sc-font-body: 'Source Serif 4', Georgia, serif; 15 --sc-font-code: 'Source Code Pro', monospace; 16 17 /* Colors */ 18 --sc-bg: #f5f0e6; 19 --sc-text: #2c2416; 20 --sc-text-dim: #8a7c6a; 21 --sc-accent: #c25832; 22 --sc-accent-soft: rgba(194, 88, 50, 0.08); 23 --sc-code-bg: #1a1a2e; 24 --sc-code-text: #d4d0c8; 25 --sc-code-gutter: #3a3a52; 26 --sc-border: rgba(44, 36, 22, 0.1); 27 --sc-focus-bg: rgba(194, 88, 50, 0.06); 28 --sc-panel-radius: 12px; 29 30 /* Syntax highlighting */ 31 --sc-hl-keyword: #f0a6a0; 32 --sc-hl-type: #8ec8e8; 33 --sc-hl-string: #b8d89a; 34 --sc-hl-comment: #6a6a82; 35 --sc-hl-number: #ddb97a; 36 --sc-hl-module: #e8c87a; 37 --sc-hl-operator: #c8a8d8; 38 --sc-hl-punct: #7a7a92; 39 40 /* Mobile */ 41 --sc-mobile-step-bg: rgba(255,255,255,0.5); 42} 43 44/* Warm hero: centered */ 45.sc-container .sc-hero { 46 text-align: center; 47 border-bottom: 1px solid var(--sc-border); 48} 49 50.sc-container .sc-hero h1 { 51 font-style: italic; 52} 53 54.sc-container .sc-hero p { 55 margin: 0 auto; 56} 57 58/* Warm code panel: navy shadow */ 59.sc-container .sc-code-panel { 60 box-shadow: 0 20px 60px rgba(26, 26, 46, 0.3), 0 0 0 1px rgba(255,255,255,0.03) inset; 61} 62 63/* Warm dots: traffic light colors */ 64.sc-container .sc-dots span:nth-child(1) { background: #ff5f57; } 65.sc-container .sc-dots span:nth-child(2) { background: #ffbd2e; } 66.sc-container .sc-dots span:nth-child(3) { background: #28c840; } 67 68/* Warm diff */ 69.sc-container .sc-diff-block { 70 background: #1e1b2e; 71} 72.sc-container .sc-diff-added { background: rgba(80, 200, 80, 0.15); border-left: 3px solid #4caf50; } 73.sc-container .sc-diff-removed { background: rgba(255, 80, 80, 0.12); border-left: 3px solid #ef5350; text-decoration: line-through; opacity: 0.7; } 74.sc-container .sc-diff-same { opacity: 0.5; } 75|} 76 77(** Dark Terminal theme. 78 Near-black background, phosphor green and amber, JetBrains Mono + Outfit. *) 79let dark_css = 80 {|@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@300..800&family=Outfit:wght@300..900&display=swap'); 81 82.sc-container { 83 /* Typography */ 84 --sc-font-display: 'Outfit', sans-serif; 85 --sc-font-body: 'Outfit', sans-serif; 86 --sc-font-code: 'JetBrains Mono', monospace; 87 88 /* Colors */ 89 --sc-bg: #0a0a0f; 90 --sc-text: #e8e6f0; 91 --sc-text-dim: #6e6b80; 92 --sc-accent: #4ade80; 93 --sc-accent-soft: rgba(74, 222, 128, 0.06); 94 --sc-code-bg: #0f0f18; 95 --sc-code-text: #c8c5d8; 96 --sc-code-gutter: #2a2a3e; 97 --sc-border: rgba(255, 255, 255, 0.06); 98 --sc-focus-bg: rgba(74, 222, 128, 0.04); 99 --sc-panel-radius: 0; 100 101 /* Syntax highlighting — neon palette */ 102 --sc-hl-keyword: #ff7eb3; 103 --sc-hl-type: #7dd3fc; 104 --sc-hl-string: #4ade80; 105 --sc-hl-comment: #4a4a62; 106 --sc-hl-number: #fbbf24; 107 --sc-hl-module: #c4b5fd; 108 --sc-hl-operator: #67e8f9; 109 --sc-hl-punct: #4a4a62; 110 111 /* Mobile */ 112 --sc-mobile-step-bg: rgba(255,255,255,0.04); 113} 114 115/* Dark hero: left-aligned, larger */ 116.sc-container .sc-hero { 117 text-align: left; 118 padding: 8rem 4rem 4rem; 119 max-width: 800px; 120 position: relative; 121} 122 123.sc-container .sc-hero::before { 124 content: ''; 125 position: absolute; 126 top: 0; left: 0; right: 0; bottom: 0; 127 background: radial-gradient(ellipse at 20% 50%, rgba(74, 222, 128, 0.04) 0%, transparent 60%); 128 pointer-events: none; 129} 130 131.sc-container .sc-hero h1 { 132 font-size: clamp(2.8rem, 6vw, 4.5rem); 133 font-weight: 800; 134 letter-spacing: -0.04em; 135 line-height: 1.0; 136 margin-bottom: 1.25rem; 137} 138 139.sc-container .sc-hero h1 em { 140 font-style: normal; 141 color: var(--sc-accent); 142} 143 144.sc-container .sc-hero p { 145 max-width: 50ch; 146 font-weight: 300; 147} 148 149/* Dark layout: narrow prose, wide code */ 150.sc-container .sc-steps-col { 151 width: 38%; 152 flex: none; 153 padding: 2rem 2.5rem 50vh 4rem; 154 border-right: 1px solid var(--sc-border); 155} 156 157.sc-container .sc-code-col { 158 flex: 1; 159 width: auto; 160} 161 162/* Dark step number: with line */ 163.sc-container .sc-step-number { 164 font-weight: 700; 165 letter-spacing: 0.15em; 166 display: flex; 167 align-items: center; 168 gap: 0.75rem; 169} 170 171.sc-container .sc-step-number::after { 172 content: ''; 173 flex: 1; 174 height: 1px; 175 background: var(--sc-border); 176} 177 178.sc-container .sc-step h2 { 179 font-size: 1.4rem; 180 line-height: 1.2; 181} 182 183.sc-container .sc-step p { 184 font-size: 0.9rem; 185 max-width: 40ch; 186 font-weight: 300; 187} 188 189/* Dark code panel: full viewport height */ 190.sc-container .sc-code-panel { 191 top: 0; 192 height: 100vh; 193 margin: 0; 194 border-radius: 0; 195 border-left: 1px solid var(--sc-border); 196 box-shadow: none; 197} 198 199.sc-container .sc-code-header { 200 padding: 1rem 1.5rem; 201 border-bottom: 1px solid var(--sc-border); 202 gap: 1rem; 203} 204 205.sc-container .sc-dots span { 206 width: 8px; 207 height: 8px; 208 background: var(--sc-code-gutter); 209} 210 211.sc-container .sc-filename { 212 color: var(--sc-text-dim); 213 text-align: left; 214} 215 216.sc-container .sc-step-badge { 217 color: var(--sc-accent); 218 background: rgba(74, 222, 128, 0.08); 219 padding: 0.25em 0.75em; 220 border-radius: 3px; 221} 222 223.sc-container .sc-code-body { 224 padding: 1.5rem 0; 225 line-height: 1.75; 226} 227 228.sc-container .sc-line { 229 padding: 0 1.5rem; 230 transition: opacity 0.3s ease, background 0.3s ease; 231 opacity: 0.25; 232} 233 234.sc-container .sc-line.sc-focused { 235 border-left: 2px solid var(--sc-accent); 236 padding-left: calc(1.5rem - 2px); 237} 238 239.sc-container .sc-line-number { 240 margin-right: 2ch; 241} 242 243/* Dark progress: right side, bar style */ 244.sc-container .sc-progress { 245 left: auto; 246 right: 1.5rem; 247 gap: 10px; 248} 249 250.sc-container .sc-pip { 251 width: 3px; 252 height: 20px; 253 border-radius: 2px; 254} 255 256.sc-container .sc-pip.sc-active { 257 box-shadow: 0 0 12px rgba(74, 222, 128, 0.5); 258 height: 30px; 259 transform: none; 260} 261 262/* Dark mobile */ 263.sc-container .sc-mobile-step { 264 border-radius: 10px; 265 border: 1px solid rgba(255,255,255,0.08); 266} 267 268.sc-container .sc-mobile-step-num { 269 font-family: var(--sc-font-body); 270 letter-spacing: 0.2em; 271 color: #00d4aa; 272} 273 274.sc-container .sc-mobile-step h2 { 275 color: #e8e6e3; 276} 277 278.sc-container .sc-mobile-step p { 279 color: rgba(232,230,227,0.7); 280} 281 282.sc-container .sc-diff-block { 283 background: #0d1117; 284 border: 1px solid rgba(0,212,170,0.15); 285} 286.sc-container .sc-diff-added { background: rgba(0, 212, 170, 0.12); border-left: 3px solid #00d4aa; } 287.sc-container .sc-diff-removed { background: rgba(255, 80, 80, 0.1); border-left: 3px solid #ff6b6b; text-decoration: line-through; opacity: 0.6; } 288.sc-container .sc-diff-same { opacity: 0.4; } 289 290.sc-container .sc-playground-btn { 291 border-color: rgba(0,212,170,0.3); 292 color: #00d4aa; 293} 294.sc-container .sc-playground-btn:hover { 295 background: rgba(0,212,170,0.1); 296 border-color: #00d4aa; 297} 298|} 299 300(** Notebook theme. 301 Soft white, blue-violet accent, Newsreader + DM Sans. *) 302let notebook_css = 303 {|@import url('https://fonts.googleapis.com/css2?family=DM+Mono:wght@300;400;500&family=DM+Sans:ital,opsz,wght@0,9..40,300..900;1,9..40,300..900&family=Newsreader:ital,opsz,wght@0,6..72,300..800;1,6..72,300..800&display=swap'); 304 305.sc-container { 306 /* Typography */ 307 --sc-font-display: 'Newsreader', serif; 308 --sc-font-body: 'DM Sans', sans-serif; 309 --sc-font-code: 'DM Mono', 'Source Code Pro', monospace; 310 311 /* Colors */ 312 --sc-bg: #fafbfe; 313 --sc-text: #1a1a2e; 314 --sc-text-dim: #64648a; 315 --sc-accent: #6366f1; 316 --sc-accent-soft: rgba(99, 102, 241, 0.06); 317 --sc-code-bg: #1e1e32; 318 --sc-code-text: #d1d0e0; 319 --sc-code-gutter: #3a3a52; 320 --sc-border: rgba(99, 102, 241, 0.08); 321 --sc-focus-bg: rgba(99, 102, 241, 0.05); 322 --sc-panel-radius: 16px; 323 324 /* Syntax highlighting — cool tones */ 325 --sc-hl-keyword: #a78bfa; 326 --sc-hl-type: #67e8f9; 327 --sc-hl-string: #86efac; 328 --sc-hl-comment: #4a4a62; 329 --sc-hl-number: #fde68a; 330 --sc-hl-module: #f9a8d4; 331 --sc-hl-operator: #93c5fd; 332 --sc-hl-punct: #4a4a62; 333 334 /* Mobile */ 335 --sc-mobile-step-bg: #ffffff; 336} 337 338/* Notebook hero: left-aligned, accent underline */ 339.sc-container .sc-hero { 340 text-align: left; 341 padding: 6rem 0 3rem; 342 max-width: 640px; 343 margin: 0 auto; 344 border-bottom: 2px solid var(--sc-accent); 345 position: relative; 346} 347 348.sc-container .sc-hero::after { 349 content: ''; 350 position: absolute; 351 bottom: -2px; left: 0; 352 width: 120px; 353 height: 2px; 354 background: var(--sc-accent); 355 box-shadow: 0 0 16px rgba(99, 102, 241, 0.4); 356} 357 358.sc-container .sc-hero h1 { 359 font-size: clamp(2rem, 4vw, 2.8rem); 360 font-weight: 600; 361 letter-spacing: -0.02em; 362 line-height: 1.15; 363} 364 365.sc-container .sc-hero p { 366 font-size: 1rem; 367 max-width: 52ch; 368 font-weight: 400; 369} 370 371/* Notebook layout: constrained width */ 372.sc-container .sc-tutorial { 373 max-width: 1200px; 374 margin: 0 auto; 375} 376 377.sc-container .sc-steps-col { 378 padding: 2rem 3rem 50vh 0; 379 max-width: 420px; 380} 381 382.sc-container .sc-code-col { 383 flex: 1; 384 width: auto; 385} 386 387/* Notebook step: accent line indicator */ 388.sc-container .sc-step { 389 min-height: 60vh; 390 padding: 1.5rem 0; 391 position: relative; 392} 393 394.sc-container .sc-step::before { 395 content: ''; 396 position: absolute; 397 left: -1.5rem; 398 top: 50%; 399 transform: translateY(-50%); 400 width: 3px; 401 height: 0; 402 background: var(--sc-accent); 403 border-radius: 2px; 404 transition: height 0.4s cubic-bezier(0.22, 1, 0.36, 1); 405} 406 407.sc-container .sc-step-number { 408 font-family: var(--sc-font-body); 409 font-weight: 700; 410 letter-spacing: 0.12em; 411 display: flex; 412 align-items: center; 413 gap: 0.5rem; 414} 415 416.sc-container .sc-step h2 { 417 font-size: 1.3rem; 418 font-weight: 600; 419 letter-spacing: -0.01em; 420 margin-bottom: 0.6rem; 421 line-height: 1.3; 422} 423 424.sc-container .sc-step p { 425 font-size: 0.88rem; 426 max-width: 42ch; 427} 428 429/* Notebook code panel */ 430.sc-container .sc-code-panel { 431 top: 8vh; 432 height: 84vh; 433 margin: 0 0 0 2rem; 434 box-shadow: 435 0 24px 80px rgba(30, 30, 50, 0.15), 436 0 0 0 1px rgba(99, 102, 241, 0.08); 437} 438 439.sc-container .sc-code-header { 440 background: rgba(99, 102, 241, 0.04); 441 border-bottom: 1px solid rgba(255,255,255,0.04); 442 gap: 0.75rem; 443} 444 445.sc-container .sc-dots span { 446 width: 9px; 447 height: 9px; 448 background: rgba(255,255,255,0.08); 449} 450 451.sc-container .sc-code-body { 452 font-size: 0.78rem; 453 line-height: 1.75; 454} 455 456.sc-container .sc-line { 457 opacity: 0.3; 458} 459 460/* Notebook progress: left side, square pips */ 461.sc-container .sc-progress { 462 left: 2rem; 463 gap: 6px; 464} 465 466.sc-container .sc-pip { 467 width: 8px; 468 height: 8px; 469 border-radius: 3px; 470} 471 472.sc-container .sc-pip.sc-active { 473 box-shadow: 0 0 10px rgba(99, 102, 241, 0.4); 474 border-radius: 2px; 475 width: 8px; 476 height: 16px; 477 transform: none; 478} 479 480/* Notebook mobile */ 481.sc-container .sc-mobile-step { 482 border-radius: 6px; 483 border: 1px solid #e0ddd8; 484} 485 486.sc-container .sc-mobile-step-num { 487 font-family: var(--sc-font-body); 488 font-weight: 600; 489 color: #0066cc; 490} 491 492.sc-container .sc-mobile-step h2 { 493 color: #1a1a1a; 494} 495 496.sc-container .sc-mobile-step p { 497 color: #4a4a4a; 498} 499 500.sc-container .sc-diff-block { 501 background: #282c34; 502 border: 1px solid #e0ddd8; 503 font-family: 'IBM Plex Mono', monospace; 504} 505.sc-container .sc-diff-added { background: rgba(0, 102, 204, 0.12); border-left: 3px solid #0066cc; } 506.sc-container .sc-diff-removed { background: rgba(220, 50, 50, 0.1); border-left: 3px solid #dc3232; text-decoration: line-through; opacity: 0.6; } 507.sc-container .sc-diff-same { opacity: 0.4; } 508 509.sc-container .sc-playground-btn { 510 border-color: rgba(0,102,204,0.3); 511 color: #0066cc; 512} 513.sc-container .sc-playground-btn:hover { 514 background: rgba(0,102,204,0.1); 515 border-color: #0066cc; 516} 517|} 518 519(** Register all theme CSS files as support files *) 520let () = 521 let register name content = 522 Odoc_extension_api.Registry.register_support_file ~prefix:"scrolly" { 523 filename = "extensions/scrollycode-" ^ name ^ ".css"; 524 content = Inline content; 525 } 526 in 527 register "warm" warm_css; 528 register "dark" dark_css; 529 register "notebook" notebook_css