Changes for page Public Web Site
Last modified by Alex Cotiugă on 2026/05/04 06:16
From version 3.42
edited by Alex Cotiugă
on 2025/11/24 10:24
on 2025/11/24 10:24
Change comment:
There is no comment for this version
To version 4.7
edited by Alex Cotiugă
on 2026/05/01 13:03
on 2026/05/01 13:03
Change comment:
There is no comment for this version
Summary
-
Page properties (1 modified, 0 added, 0 removed)
-
Objects (1 modified, 0 added, 0 removed)
Details
- Page properties
-
- Content
-
... ... @@ -5,21 +5,22 @@ 5 5 ## HERO 6 6 <section class="hero hero-centered" aria-labelledby="hero-title"> 7 7 <div class="container hero-inner"> 8 - <h1 id="hero-title">Professional XWiki solutions, from setup to long-term stability</h1> 9 - <p class="lead">Need your XWiki upgraded, secured, or improved? Let’s make it happen.</p> 10 - <div class="hero-cta"> 11 - <a class="btn btn-primary" href="#contact" aria-label="Request a consultation" data-toggle="modal" data-target="#requestConsultation"> 12 - Request a consultation 13 - </a> 14 - #requestConsultationModal() 15 - ##data-toggle="modal" data-target="#requestConsultationModal" 16 - </div> 8 + <h1 id="hero-title">Keep Your XWiki Platform Secure, Stable and Up-to-Date</h1> 9 + <p class="lead">Helping organizations safely upgrade and maintain their XWiki environments.</p> 17 17 <ul class="benefits"> 18 - <li>Smooth upgrades</li> 11 + <li><a href="$xwiki.getURL('services.xwiki-upgrades')">Smooth upgrades</a></li> 19 19 <li>Reliable support plans</li> 20 20 <li>Custom integrations</li> 21 21 <li>Secure, optimized platforms</li> 22 22 </ul> 16 + <div class="hero-cta"> 17 + <a href="mailto:alex@agnease.com">Contact Agnease</a> 18 + #*<a class="btn btn-primary" href="#contact" aria-label="Request a consultation" data-toggle="modal" data-target="#requestConsultation"> 19 + Request a consultation 20 + </a> 21 + #requestConsultationModal()*# 22 + ##data-toggle="modal" data-target="#requestConsultationModal" 23 + </div> 23 23 </div> 24 24 </section> 25 25 ## WHY CHOOSE ... ... @@ -60,6 +60,7 @@ 60 60 ## SERVICES 61 61 #set ($servicesSectionData = [{ 62 62 'title': 'Upgrades', 64 + 'reference': 'services.xwiki-upgrades', 63 63 'icon': 'refresh', 64 64 'content': 'Stay current with the latest XWiki LTS and keep your instance reliable.', 65 65 'items': [ ... ... @@ -125,7 +125,13 @@ 125 125 <i class="fa fa-$entry.icon" aria-hidden="true"></i> 126 126 </div> 127 127 <div class="service-body"> 128 - <h4>$entry.title</h4> 130 + <h4> 131 + #if ("$!entry.reference" != '') 132 + <a href="$xwiki.getURL($entry.reference)">$entry.title</a> 133 + #else 134 + $entry.title 135 + #end 136 + </h4> 129 129 <p>$entry.content</p> 130 130 <ul> 131 131 #foreach ($item in $entry.items) ... ... @@ -159,17 +159,59 @@ 159 159 </div> 160 160 <div class="modal-body"> 161 161 <div> 162 - $services.localization.render('blog.modal.checkCategorySelection.body') 170 + ##Need help with your XWiki? <a href="mailto:alex@agnease.com">Contact Agnease</a> 171 + #displayFormFromSheetCode() 163 163 </div> 164 164 </div> 165 165 <div class="modal-footer"> 166 - <input id="continueCategorySelection" type="button" class="btn btn-default" data-dismiss="modal" 167 - value="$escapetool.xml($services.localization.render('yesno_1'))"> 168 - <input type="button" class="btn btn-danger" data-dismiss="modal" 169 - value="$escapetool.xml($services.localization.render('blog.modal.checkCategorySelection.footer.no'))"> 175 + ##<input id="continueCategorySelection" type="button" class="btn btn-default" data-dismiss="modal" 176 + ## value="$escapetool.xml($services.localization.render('yesno_1'))"> 170 170 </div> 171 171 </div> 172 172 </div> 173 173 </div> 174 174 #end 182 + 183 +#macro (stripHTMLMacro $displayOutput) 184 + $stringtool.removeEnd($stringtool.removeStart($displayOutput, '{{html clean="false" wiki="false"}}'), '{{/html}}').replace('Agnease.Code.Lead.LeadClass_0_', 'acl-') 185 +#end 186 + 187 +#macro (displayFormFromSheetCode) 188 + #set ($editing = true) 189 + ## The object to display. 190 + #set ($xobject = $doc.newObject('Agnease.Code.Lead.LeadClass')) 191 + ## The class that describes the object properties. 192 + #set ($xclass = $xwiki.getClass('Agnease.Code.Lead.LeadClass')) 193 + ## Make sure the following display* method calls use the right object. 194 + #set ($discard = $doc.use($xobject)) 195 + ## Using the xform vertical form layout. 196 + <div class="xform"> 197 + <dl> 198 + #foreach ($property in $xclass.properties) 199 + #if ($property.name != 'status') 200 + <dt #if (!$editing) 201 + class="editableProperty" 202 + #set ($xobjectPropertyReference = $xobject.getPropertyReference($property.name)) 203 + data-property="$escapetool.xml($services.model.serialize($xobjectPropertyReference))" 204 + data-property-type="object"#end> 205 + ## This must match the id generated by the $doc.display() method below. 206 + #set ($propertyId = "acl-$property.name") 207 + <label#if ($editing) for="$escapetool.xml($propertyId)"#end> 208 + $escapetool.xml($property.translatedPrettyName) 209 + </label> 210 + ## Support for specifying a translation key as hint in the property definition. 211 + <span class="xHint">$!escapetool.xml($services.localization.render($property.hint))</span> 212 + </dt> 213 + #set ($displayOutput = $doc.display($property.name, 'edit')) 214 + <dd>#stripHTMLMacro($displayOutput)</dd> 215 + #end 216 + #end 217 + #if (!$xclass.properties || $xclass.properties.size() == 0) 218 + ## Keep the empty definition term in order to have valid HTML. 219 + <dt></dt> 220 + <dd>$escapetool.xml($services.localization.render('xclass.defaultObjectSheet.noProperties'))</dd> 221 + #end 222 + </dl> 223 + </div> 224 +#end 175 175 {{/velocity}}
- XWiki.StyleSheetExtension[0]
-
- code
-
... ... @@ -1,9 +1,11 @@ 1 -/* ========== Agnease Landing (no Bootstrap grid) ========== */ 1 +/* ========== Agnease Public Website Theme ========== */ 2 + 2 2 @brand: #00937D; 3 3 @brand-strong: #007B6A; 4 4 @text: #2D3A34; 5 5 @muted: #5B6B64; 6 6 @line: #E4ECE9; 8 +@soft: #F6FBF9; 7 7 @radius: 16px; 8 8 @shadow-sm: 0 6px 20px rgba(0,0,0,.06); 9 9 @shadow: 0 12px 36px rgba(0,0,0,.08); ... ... @@ -15,13 +15,26 @@ 15 15 16 16 .container { 17 17 max-width: @maxw; 20 + margin-left: auto; 21 + margin-right: auto; 18 18 } 19 19 24 +.text-center { 25 + text-align: center; 26 +} 27 + 20 20 .lead { 21 21 color: @muted; 22 22 text-align: center; 31 + line-height: 1.5; 23 23 } 24 -h2 { 33 + 34 +.page-lead { 35 + max-width: 760px; 36 + margin: 0 auto; 37 + color: @muted; 38 + font-size: 18px; 39 + line-height: 1.5; 25 25 text-align: center; 26 26 } 27 27 ... ... @@ -34,89 +34,145 @@ 34 34 } 35 35 } 36 36 37 -/* Buttons */ 38 -.btn { 39 - display: inline-flex; 40 - align-items: center; 41 - justify-content: center; 42 - padding: .85rem 1.1rem; 43 - border-radius: 12px; 44 - border: 2px solid transparent; 45 - font-weight: 650; 46 - letter-spacing: .2px; 47 - cursor: pointer; 48 - box-shadow: @shadow-sm; 52 +h1, h2, h3, h4 { 53 + color: @text; 54 +} 49 49 50 - /*&:focus-visible { 51 - outline: 3px solid @brand; 52 - outline-offset: 2px; 53 - }*/ 56 +h2 { 57 + text-align: center; 54 54 } 55 55 56 -/* ===== HERO ===== */ 57 -.hero { 58 - overflow: hidden; 59 - background-repeat: no-repeat; 60 - background-attachment: scroll; 60 +/* ===== Buttons / links ===== */ 61 61 62 - &.hero-centered { 63 - text-align: center; 64 - background: 65 - radial-gradient(50rem 18rem at 50% -10%, #E7FFF8 0%, transparent 60%), 66 - radial-gradient(50rem 18rem at 50% 0%, #E8F6F3 0%, transparent 60%); 67 - display: flex; 68 - align-items: center; 69 - justify-content: center; 70 - min-height: 350px; 71 - } 62 +.btn-main, 63 +.btn-secondary { 64 + display: inline-block; 65 + border-radius: 8px; 66 + padding: 9px 14px; 67 + font-weight: 700; 68 + text-decoration: none; 69 + line-height: 1.2; 70 +} 72 72 73 - .hero-inner { 74 - max-width: 850px; 75 - margin: 0 auto; 76 - display: flex; 77 - flex-direction: column; 78 - align-items: center; 72 +.btn-main { 73 + color: #fff; 74 + background: @brand; 75 + 76 + &:hover, 77 + &:focus { 78 + color: #fff; 79 + background: @brand-strong; 80 + text-decoration: none; 79 79 } 82 +} 80 80 81 - .hero-cta { 82 - display: flex; 83 - gap: 0.8rem; 84 - flex-wrap: wrap; 85 - justify-content: center; 86 - margin-top: 0.3rem; 84 +.btn-secondary { 85 + color: @brand; 86 + background: fade(@brand, 8%); 87 + border: 1px solid fade(@brand, 20%); 88 + 89 + &:hover, 90 + &:focus { 91 + color: @brand-strong; 92 + background: fade(@brand, 12%); 93 + text-decoration: none; 87 87 } 95 +} 88 88 89 - .benefits { 90 - display: flex; 91 - flex-wrap: wrap; 92 - justify-content: center; 93 - list-style: none; 94 - padding: 0; 95 - margin: 0.8rem 0 0; 96 - color: @muted; 97 - font-size: 14px; 97 +.cta-row { 98 + display: flex; 99 + gap: 10px; 100 + flex-wrap: wrap; 101 + justify-content: center; 102 + margin-top: 16px; 103 +} 98 98 99 - li + li::before { 100 - content: "•"; 101 - margin: 0 5px; 102 - } 105 +/* ===== Landing page hero ===== */ 103 103 104 - @media (max-width: 640px) { 105 - li + li::before { 106 - content: none; 107 - } 108 - li:nth-child(1)::after, 109 - li:nth-child(3)::after { 110 - content: "•"; 111 - margin: 0 5px; 112 - } 113 - } 114 - } 107 +.landing-hero { 108 + text-align: center; 109 + min-height: 340px; 110 + display: flex; 111 + align-items: center; 112 + justify-content: center; 113 + background: 114 + radial-gradient(50rem 18rem at 50% -10%, #E7FFF8 0%, transparent 60%), 115 + radial-gradient(50rem 18rem at 50% 0%, #E8F6F3 0%, transparent 60%); 115 115 } 116 116 117 -/* ===== WHY CHOOSE (cards) ===== */ 118 +.landing-hero-inner { 119 + max-width: 860px; 120 + margin: 0 auto; 121 +} 122 + 123 +.landing-hero h1 { 124 + margin: 0 0 10px; 125 + font-size: 36px; 126 + line-height: 1.18; 127 +} 128 + 129 +.landing-hero .lead { 130 + margin: 0 auto 12px; 131 + max-width: 760px; 132 + font-size: 18px; 133 +} 134 + 135 +/* ===== Compact page header for section pages ===== */ 136 + 137 +.page-header-compact { 138 + padding: 34px 0 28px; 139 + text-align: center; 140 + border-top: none; 141 + background: 142 + radial-gradient(42rem 12rem at 50% -20%, #E7FFF8 0%, transparent 65%); 143 +} 144 + 145 +.page-header-compact .container { 146 + max-width: 850px; 147 +} 148 + 149 +.page-eyebrow { 150 + margin: 0 0 8px; 151 + color: @brand; 152 + font-size: 12px; 153 + font-weight: 800; 154 + text-transform: uppercase; 155 + letter-spacing: .08em; 156 +} 157 + 158 +.page-header-compact h1 { 159 + margin: 0 0 10px; 160 + font-size: 34px; 161 + line-height: 1.15; 162 +} 163 + 164 +/* ===== Benefits / chips ===== */ 165 + 166 +.benefits, 167 +.inline-benefits { 168 + display: flex; 169 + flex-wrap: wrap; 170 + justify-content: center; 171 + gap: 8px; 172 + list-style: none; 173 + padding: 0; 174 + margin: 12px 0 0; 175 +} 176 + 177 +.benefits li, 178 +.inline-benefits li { 179 + color: @muted; 180 + font-size: 13px; 181 + background: fade(@brand, 8%); 182 + border: 1px solid fade(@brand, 18%); 183 + border-radius: 999px; 184 + padding: 4px 10px; 185 +} 186 + 187 +/* ===== Cards ===== */ 188 + 118 118 .widgets { 119 - margin-top: 1 2px;190 + margin-top: 16px; 120 120 display: grid; 121 121 grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); 122 122 grid-gap: 16px; ... ... @@ -145,8 +145,16 @@ 145 145 padding-bottom: 6px; 146 146 margin-bottom: 8px; 147 147 border-bottom: 1px solid fade(@line, 60%); 148 - i { color: @brand; } 149 - h4 { margin: 0; line-height: 1.2; color: @text; } 219 + 220 + i { 221 + color: @brand; 222 + } 223 + 224 + h4 { 225 + margin: 0; 226 + line-height: 1.2; 227 + color: @text; 228 + } 150 150 } 151 151 152 152 p { ... ... @@ -154,101 +154,278 @@ 154 154 color: @muted; 155 155 line-height: 1.45; 156 156 } 236 + 237 + .card-link { 238 + margin-top: 12px; 239 + 240 + a { 241 + color: @brand; 242 + font-weight: 700; 243 + text-decoration: none; 244 + 245 + &:hover { 246 + color: @brand-strong; 247 + text-decoration: underline; 248 + } 249 + } 250 + } 157 157 } 158 158 159 -/* ===== SERVICES ===== */ 160 -.services { 161 - .services-grid { 162 - margin-top: 20px; 163 - display: flex; 164 - flex-wrap: wrap; 165 - gap: 24px; 253 +/* ===== Service / listing rows ===== */ 166 166 167 - /* center the whole block under the heading */ 168 - max-width: 960px; 169 - margin-left: auto; 170 - margin-right: auto; 171 - justify-content: center; 255 +.services-grid { 256 + margin-top: 20px; 257 + display: flex; 258 + flex-wrap: wrap; 259 + gap: 24px; 260 + max-width: 960px; 261 + margin-left: auto; 262 + margin-right: auto; 263 + justify-content: center; 264 +} 265 + 266 +.service { 267 + flex: 0 1 calc(50% - 12px); 268 + display: flex; 269 + align-items: flex-start; 270 + gap: 16px; 271 + margin-bottom: 8px; 272 +} 273 + 274 +.service-icon { 275 + width: 42px; 276 + height: 42px; 277 + border-radius: 50%; 278 + display: flex; 279 + align-items: center; 280 + justify-content: center; 281 + color: @brand; 282 + background: fade(@brand, 10%); 283 + flex-shrink: 0; 284 + margin-top: 3px; 285 +} 286 + 287 +.service-body { 288 + h4 { 289 + margin: 0 0 4px; 290 + font-size: 1.125rem; 291 + font-weight: 800; 292 + 293 + a { 294 + color: @text; 295 + text-decoration: none; 296 + 297 + &:hover { 298 + color: @brand; 299 + text-decoration: underline; 300 + } 301 + } 172 172 } 173 173 174 - .service { 175 - flex: 0 1 calc(50% - 12px); 176 - display: flex; 177 - align-items: flex-start; 178 - gap: 16px; 179 - margin-bottom: 8px; 304 + p { 305 + margin: 0 0 6px; 306 + color: @text; 307 + line-height: 1.5; 308 + } 180 180 181 - .service-icon { 182 - width: 42px; 183 - height: 42px; 184 - border-radius: 50%; 185 - display: flex; 186 - align-items: center; 187 - justify-content: center; 188 - font-size: 18px; 310 + ul { 311 + margin: .45rem 0 0; 312 + padding-left: 1.1rem; 313 + color: @muted; 314 + font-size: 13px; 315 + } 316 + 317 + li { 318 + margin: .25rem 0; 319 + line-height: 1.45; 320 + } 321 + 322 + .service-link { 323 + margin-top: .45rem; 324 + font-size: 13px; 325 + 326 + a { 189 189 color: @brand; 190 - background: fade(@brand, 10%); 191 - flex-shrink: 0; 192 - margin-top: 3px; 193 - } 328 + font-weight: 700; 329 + text-decoration: none; 194 194 195 - .service-body { 196 - h4 { 197 - margin: 0 0 4px; 198 - font-size: 1.125rem; 199 - font-weight: 800; 331 + &:hover { 332 + color: @brand-strong; 333 + text-decoration: underline; 200 200 } 201 - p { 202 - margin: 0 0 6px; 203 - color: @text; 204 - line-height: 1.5; 205 - } 206 - ul { 207 - margin: .45rem 0 0; 208 - padding-left: 1.1rem; 209 - color: @muted; 210 - font-size: 13px; 211 - } 212 - li { 213 - margin: .25rem 0; 214 - line-height: 1.45; 215 - } 216 216 } 217 217 } 337 +} 218 218 219 - /* ==== Center last item on its own row while keeping 50% width ==== */ 220 - .service-center { 221 - /* same width as siblings */ 222 - flex: 0 1 calc(55% - 12px); 339 +/* ===== Split section ===== */ 223 223 224 - /* push to center */ 225 - margin-left: auto; 226 - margin-right: auto; 341 +.split-section { 342 + display: grid; 343 + grid-template-columns: minmax(0, 1.1fr) minmax(280px, .9fr); 344 + gap: 32px; 345 + align-items: start; 346 + max-width: 960px; 347 + margin: 0 auto; 348 +} 349 + 350 +.panel { 351 + background: #fff; 352 + border: 1px solid @line; 353 + border-radius: @radius; 354 + box-shadow: @shadow-sm; 355 + padding: 20px; 356 +} 357 + 358 +.panel h3 { 359 + margin-top: 0; 360 +} 361 + 362 +/* ===== Contact / form page ===== */ 363 + 364 +.contact-layout { 365 + display: grid; 366 + grid-template-columns: minmax(0, .85fr) minmax(320px, 1.15fr); 367 + gap: 32px; 368 + max-width: 1000px; 369 + margin: 0 auto; 370 + align-items: start; 371 +} 372 + 373 +.contact-card { 374 + background: #fff; 375 + border: 1px solid @line; 376 + border-radius: @radius; 377 + box-shadow: @shadow-sm; 378 + padding: 20px; 379 +} 380 + 381 +.contact-card h3 { 382 + margin-top: 0; 383 +} 384 + 385 +.contact-list { 386 + list-style: none; 387 + padding: 0; 388 + margin: 12px 0 0; 389 + 390 + li { 391 + margin: 8px 0; 392 + color: @muted; 227 227 } 228 228 229 - /* Mobile: 1 per row */ 230 - @media (max-width: 767px) { 231 - .services-grid { 232 - gap: 16px; 233 - max-width: 100%; 234 - } 395 + i { 396 + color: @brand; 397 + margin-right: 8px; 398 + } 235 235 236 - .service, 237 - .service-center { 238 - flex: 0 1 100%; 239 - margin-left: 0; 240 - margin-right: 0; 241 - } 400 + a { 401 + color: @brand; 242 242 } 243 243 } 244 244 405 +.form-panel { 406 + background: #fff; 407 + border: 1px solid @line; 408 + border-radius: @radius; 409 + box-shadow: @shadow-sm; 410 + padding: 22px; 411 +} 412 + 413 +.form-panel .xform dl { 414 + margin: 0; 415 +} 416 + 417 +.form-panel .xform dt { 418 + margin-top: 12px; 419 +} 420 + 421 +.form-panel .xform dt:first-child { 422 + margin-top: 0; 423 +} 424 + 425 +.form-panel .xform label { 426 + color: @text; 427 + font-weight: 700; 428 +} 429 + 430 +.form-panel .xform .xHint { 431 + display: block; 432 + color: @muted; 433 + font-size: 12px; 434 + margin-top: 2px; 435 +} 436 + 437 +.form-panel .xform dd { 438 + margin-left: 0; 439 + margin-bottom: 10px; 440 +} 441 + 442 +.form-panel input[type="text"], 443 +.form-panel input[type="email"], 444 +.form-panel textarea, 445 +.form-panel select { 446 + width: 100%; 447 + max-width: 100%; 448 + border: 1px solid @line; 449 + border-radius: 8px; 450 + padding: 8px 10px; 451 +} 452 + 245 245 /* ===== CTA ===== */ 454 + 246 246 .cta-section { 247 247 padding: 24px 0 16px; 457 +} 248 248 249 - .contact-inline { 250 - margin: 0; 251 - color: @muted; 252 - a { color: @brand; } 459 +.contact-inline { 460 + margin: 0; 461 + color: @muted; 462 + 463 + a { 464 + color: @brand; 465 + font-weight: 700; 253 253 } 254 254 } 468 + 469 +/* ===== Compact sections ===== */ 470 + 471 +.compact-section { 472 + padding: 28px 0; 473 +} 474 + 475 +.compact-section h2 { 476 + margin-top: 0; 477 + margin-bottom: 14px; 478 +} 479 + 480 +/* ===== Responsive ===== */ 481 + 482 +@media (max-width: 767px) { 483 + section { 484 + padding: 26px 0; 485 + } 486 + 487 + .landing-hero { 488 + min-height: 280px; 489 + } 490 + 491 + .landing-hero h1, 492 + .page-header-compact h1 { 493 + font-size: 28px; 494 + } 495 + 496 + .page-lead, 497 + .landing-hero .lead { 498 + font-size: 16px; 499 + } 500 + 501 + .service { 502 + flex: 0 1 100%; 503 + } 504 + 505 + .split-section, 506 + .contact-layout { 507 + grid-template-columns: 1fr; 508 + gap: 20px; 509 + } 510 +}