|
311 | 311 | } |
312 | 312 |
|
313 | 313 | /* ============================================ |
314 | | - Hero consensus lattice — components/HeroSection/ConsensusLattice |
| 314 | + Hero brand scene — components/HeroSection/HieroMarkScene |
315 | 315 |
|
316 | | - A real 3D scene rather than a picture of one: five node timelines standing |
317 | | - around a circle, five rings for the consensus rounds, and gossip crossing |
318 | | - between them, all in the browser's own perspective so depth comes from the |
319 | | - projection instead of from shading. |
320 | | -
|
321 | | - The scene turns through a limited arc — roughly ±15° — rather than spinning. |
322 | | - That is a rendering decision as much as a calm one: at that amplitude a flat |
323 | | - disc foreshortens by under 4%, so every point can stay a plain round div |
324 | | - and none of the ~50 elements needs a counter-rotation to keep facing front. |
| 316 | + Hedera's homepage gives the right side of its hero to one tall, luminous |
| 317 | + visual and lets a dark gradient blend that object back into the copy. This |
| 318 | + follows the same composition with Hiero's own material: the real monogram |
| 319 | + is embedded in a ledger plane, while rails and event nodes connect it to |
| 320 | + the gossip field already spread behind the hero. |
325 | 321 | ============================================ */ |
326 | 322 |
|
327 | | - /* Below `xl` the lattice is a band of its own between the credential and the |
328 | | - wordmark. The space above the wordmark was empty at those widths and the |
329 | | - object was bled so far past the right edge that only a cropped sliver of it |
330 | | - stayed on screen; giving it a row in the flow fixes both at once, and the |
331 | | - hero is content-height there so no gap is left over to fill. |
| 323 | + .hero-mark-scene { |
| 324 | + @apply pointer-events-none relative mt-1 h-[clamp(12rem,38vw,17rem)] w-full; |
| 325 | + @apply xl:absolute xl:inset-y-0 xl:right-[-3%] xl:left-auto xl:mt-0; |
| 326 | + @apply xl:h-auto xl:w-[60%] xl:-z-10; |
332 | 327 |
|
333 | | - From `xl` there is a free half to stand it in, so it lifts out of the flow |
334 | | - and takes the right of the frame, bled past the edge — the object carries |
335 | | - on past the frame rather than sitting inside it like a stock illustration. */ |
336 | | - .hero-lattice { |
337 | | - @apply pointer-events-none relative grid w-full place-items-center; |
338 | | - @apply mt-3 h-34 perspective-[74rem] sm:h-[clamp(9.5rem,24vh,16rem)]; |
339 | | - @apply xl:mt-0; |
340 | | - @apply xl:absolute xl:inset-y-0 xl:right-[-4%] xl:left-auto xl:-z-10; |
341 | | - @apply xl:h-auto xl:w-[min(48rem,56%)]; |
| 328 | + mask-image: linear-gradient( |
| 329 | + to right, |
| 330 | + transparent 0%, |
| 331 | + black 19%, |
| 332 | + black 100% |
| 333 | + ); |
342 | 334 | } |
343 | 335 |
|
344 | | - .hero-lattice-tilt { |
345 | | - --tilt-x: 0deg; |
346 | | - --tilt-y: 0deg; |
| 336 | + /* A soft pool of brand light makes the white mark feel lit by the scene, |
| 337 | + rather than laid on top of it. */ |
| 338 | + .hero-mark-scene::before { |
| 339 | + @apply absolute top-1/2 right-[-10%] h-[125%] w-[88%] -translate-y-1/2; |
| 340 | + |
| 341 | + content: ""; |
| 342 | + background: radial-gradient( |
| 343 | + ellipse, |
| 344 | + rgb(255 158 199 / 50%) 0%, |
| 345 | + rgb(217 45 106 / 24%) 40%, |
| 346 | + transparent 72% |
| 347 | + ); |
| 348 | + } |
347 | 349 |
|
348 | | - /* Long enough that the object follows the pointer rather than snapping to |
349 | | - it, which is what makes it read as mass. */ |
350 | | - @apply transform-3d transition-transform duration-500; |
351 | | - @apply ease-[cubic-bezier(0.22,0.85,0.28,1)] motion-reduce:transition-none; |
| 350 | + /* The angled ledger plane gives the mark a setting and depth. Its grid is |
| 351 | + deliberately sparse enough to remain texture behind the logo. */ |
| 352 | + .hero-mark-grid { |
| 353 | + @apply absolute top-[12%] right-[-7%] h-[76%] w-[78%]; |
| 354 | + @apply border border-white/14 shadow-[0_34px_70px_rgb(25_1_10_/_28%)]; |
352 | 355 |
|
353 | | - transform: rotateX(var(--tilt-x)) rotateY(var(--tilt-y)); |
| 356 | + clip-path: polygon(11% 0, 100% 0, 89% 100%, 0 100%); |
| 357 | + background: |
| 358 | + repeating-linear-gradient( |
| 359 | + 90deg, |
| 360 | + transparent 0 4.9rem, |
| 361 | + rgb(255 255 255 / 7%) 4.9rem calc(4.9rem + 1px) |
| 362 | + ), |
| 363 | + repeating-linear-gradient( |
| 364 | + 0deg, |
| 365 | + transparent 0 4rem, |
| 366 | + rgb(255 255 255 / 6%) 4rem calc(4rem + 1px) |
| 367 | + ), |
| 368 | + linear-gradient(135deg, rgb(255 255 255 / 9%), rgb(255 255 255 / 1%)); |
| 369 | + transform: perspective(60rem) rotateY(-12deg) rotateZ(-5deg); |
354 | 370 | } |
355 | 371 |
|
356 | | - /* The scene is authored at a fixed size in px so the geometry stays exact, |
357 | | - then scaled once here to meet the viewport. A ladder rather than a fluid |
358 | | - clamp: `scale` takes a number, and a number cannot be calc'd against vw. */ |
359 | | - .hero-lattice-stage { |
360 | | - @apply relative h-0 w-0 transform-3d; |
361 | | - @apply scale-[0.42] sm:scale-[0.5] md:scale-[0.56]; |
362 | | - @apply xl:scale-[0.88] min-[90rem]:scale-100; |
| 372 | + .hero-mark-rail { |
| 373 | + @apply absolute right-[-12%] h-px w-[88%] origin-right rotate-[-13deg]; |
363 | 374 |
|
364 | | - transform: rotateX(9deg); |
365 | | - animation: hero-lattice-turn 26s ease-in-out infinite alternate; |
| 375 | + background: linear-gradient( |
| 376 | + to right, |
| 377 | + transparent, |
| 378 | + rgb(255 255 255 / 25%) 20%, |
| 379 | + rgb(255 207 228 / 76%) 64%, |
| 380 | + transparent |
| 381 | + ); |
| 382 | + box-shadow: 0 0 18px rgb(255 156 198 / 35%); |
366 | 383 | } |
367 | 384 |
|
368 | | - /* A pool of light on the ground plane. It is the one piece of the scene that |
369 | | - is not structure — it is there so the lattice reads as standing in a space |
370 | | - rather than floating in front of a gradient. */ |
371 | | - .hero-lattice-stage::before { |
372 | | - @apply absolute top-0 left-0 h-[470px] w-[470px] rounded-full; |
373 | | - @apply -mt-[235px] -ml-[235px]; |
| 385 | + .hero-mark-rail::after { |
| 386 | + @apply absolute top-[-2px] left-[18%] h-[5px] w-[5px] rounded-full bg-white; |
| 387 | + @apply shadow-[0_0_12px_rgb(255_174_208_/_95%)]; |
374 | 388 |
|
375 | 389 | content: ""; |
376 | | - background: radial-gradient( |
377 | | - circle, |
378 | | - rgb(255 150 195 / 40%), |
379 | | - rgb(217 45 106 / 14%) 40%, |
380 | | - transparent 66% |
381 | | - ); |
382 | | - transform: translate3d(0, 196px, 0) rotateX(90deg); |
383 | 390 | } |
384 | 391 |
|
385 | | - .hero-lattice-ring, |
386 | | - .hero-lattice-column, |
387 | | - .hero-lattice-node, |
388 | | - .hero-lattice-edge { |
389 | | - @apply absolute top-0 left-0; |
| 392 | + .hero-mark-rail--top { |
| 393 | + @apply top-[23%]; |
| 394 | + } |
| 395 | + |
| 396 | + .hero-mark-rail--middle { |
| 397 | + @apply top-[52%] right-[-4%] w-[94%]; |
390 | 398 | } |
391 | 399 |
|
392 | | - /* Rounds. Lying flat in the ground plane, they project as ellipses, which is |
393 | | - what tells the eye there is a third axis before anything starts moving. */ |
394 | | - .hero-lattice-ring { |
395 | | - @apply rounded-full border border-white/30; |
396 | | - @apply shadow-[0_0_24px_rgb(255_130_185_/_16%),inset_0_0_32px_rgb(255_130_185_/_8%)]; |
| 400 | + .hero-mark-rail--bottom { |
| 401 | + @apply top-[79%] right-[-18%] w-[82%]; |
397 | 402 | } |
398 | 403 |
|
399 | | - /* Node timelines. Equal length, equal weight, equal distance from a centre |
400 | | - that is deliberately empty. */ |
401 | | - .hero-lattice-column { |
402 | | - @apply -ml-[0.5px] w-px; |
| 404 | + .hero-mark-emblem, |
| 405 | + .hero-mark-echo { |
| 406 | + @apply absolute top-1/2 right-[7%] aspect-square w-[min(13rem,56vw)]; |
403 | 407 |
|
404 | | - background: linear-gradient( |
405 | | - to bottom, |
406 | | - transparent, |
407 | | - rgb(255 255 255 / 52%) 18%, |
408 | | - rgb(255 255 255 / 52%) 82%, |
409 | | - transparent |
410 | | - ); |
| 408 | + translate: 0 -50%; |
411 | 409 | } |
412 | 410 |
|
413 | | - .hero-lattice-node { |
414 | | - @apply -mt-1.5 -ml-1.5 h-3 w-3 rounded-full; |
415 | | - @apply shadow-[0_0_12px_rgb(255_160_200_/_90%),0_0_30px_rgb(217_45_106_/_60%)]; |
| 411 | + /* The echo is a low-contrast second plane, not a second logo. It gives the |
| 412 | + solid mark a trailing edge like the layered forms in the reference. */ |
| 413 | + .hero-mark-echo { |
| 414 | + @apply right-[2%] opacity-12; |
416 | 415 |
|
417 | | - background: radial-gradient( |
418 | | - circle, |
419 | | - var(--color-white) 0 30%, |
420 | | - rgb(255 210 230 / 95%) 46%, |
421 | | - rgb(233 92 148 / 70%) 62%, |
422 | | - transparent 72% |
423 | | - ); |
| 416 | + filter: blur(0.4px); |
| 417 | + scale: 1.13; |
| 418 | + translate: 0 -43%; |
424 | 419 | } |
425 | 420 |
|
426 | | - .hero-lattice-edge { |
427 | | - @apply -mt-[0.5px] h-px origin-left; |
| 421 | + .hero-mark-emblem { |
| 422 | + @apply grid place-items-center rounded-[clamp(1.5rem,3vw,3rem)]; |
| 423 | + @apply border border-white/22; |
| 424 | + @apply shadow-[0_34px_85px_rgb(29_2_12_/_45%),inset_0_1px_0_rgb(255_255_255_/_20%)]; |
428 | 425 |
|
429 | | - background: linear-gradient( |
430 | | - to right, |
431 | | - rgb(255 255 255 / 6%), |
432 | | - rgb(255 186 214 / 85%), |
433 | | - rgb(255 255 255 / 6%) |
434 | | - ); |
| 426 | + background: |
| 427 | + radial-gradient( |
| 428 | + circle at 30% 18%, |
| 429 | + rgb(255 255 255 / 17%), |
| 430 | + transparent 38% |
| 431 | + ), |
| 432 | + linear-gradient(145deg, rgb(104 12 48 / 72%), rgb(50 4 20 / 44%)); |
| 433 | + backdrop-filter: blur(6px); |
435 | 434 | } |
436 | 435 |
|
437 | | - /* One gossip event travelling the edge it was sent along. The timelines and |
438 | | - rounds are the structure; this is the only thing in the scene that is an |
439 | | - event, so it is the only thing that moves along a path. */ |
440 | | - .hero-lattice-edge::after { |
441 | | - @apply absolute top-[-2px] left-0 h-[5px] w-[5px] rounded-full bg-white; |
442 | | - @apply shadow-[0_0_10px_rgb(255_170_205_/_90%)]; |
| 436 | + .hero-mark-emblem::before { |
| 437 | + @apply absolute inset-[5%] rounded-[inherit] border border-white/8; |
443 | 438 |
|
444 | 439 | content: ""; |
445 | | - animation: hero-lattice-gossip 4.4s ease-in-out infinite; |
446 | | - animation-delay: var(--edge-delay, 0ms); |
447 | 440 | } |
448 | 441 |
|
449 | | - @keyframes hero-lattice-turn { |
| 442 | + .hero-mark-image { |
| 443 | + @apply h-[72%] w-[72%] object-contain; |
| 444 | + |
| 445 | + filter: brightness(0) invert(1) drop-shadow(0 0 24px rgb(255 181 213 / 34%)); |
| 446 | + } |
| 447 | + |
| 448 | + .hero-mark-node { |
| 449 | + @apply absolute h-2.5 w-2.5 rounded-full bg-white; |
| 450 | + @apply shadow-[0_0_12px_rgb(255_174_208_/_95%),0_0_34px_rgb(217_45_106_/_75%)]; |
| 451 | + } |
| 452 | + |
| 453 | + .hero-mark-node--one { |
| 454 | + @apply top-[19%] right-[43%]; |
| 455 | + } |
| 456 | + |
| 457 | + .hero-mark-node--two { |
| 458 | + @apply top-[39%] right-[12%] h-1.5 w-1.5; |
| 459 | + } |
| 460 | + |
| 461 | + .hero-mark-node--three { |
| 462 | + @apply right-[49%] bottom-[20%] h-1.5 w-1.5; |
| 463 | + } |
| 464 | + |
| 465 | + .hero-mark-node--four { |
| 466 | + @apply right-[5%] bottom-[12%]; |
| 467 | + } |
| 468 | + |
| 469 | + @media (min-width: 80rem) { |
| 470 | + .hero-mark-emblem, |
| 471 | + .hero-mark-echo { |
| 472 | + @apply right-[8%] w-[min(33rem,66%)]; |
| 473 | + } |
| 474 | + |
| 475 | + .hero-mark-echo { |
| 476 | + @apply right-[3%]; |
| 477 | + } |
| 478 | + } |
| 479 | + |
| 480 | + @media (prefers-reduced-motion: no-preference) { |
| 481 | + .hero-mark-emblem { |
| 482 | + animation: hero-mark-float 8s ease-in-out infinite alternate; |
| 483 | + } |
| 484 | + |
| 485 | + .hero-mark-grid { |
| 486 | + animation: hero-mark-plane 12s ease-in-out infinite alternate; |
| 487 | + } |
| 488 | + |
| 489 | + .hero-mark-rail::after { |
| 490 | + animation: hero-mark-signal 5.5s ease-in-out infinite; |
| 491 | + } |
| 492 | + |
| 493 | + .hero-mark-rail--middle::after { |
| 494 | + animation-delay: -1.8s; |
| 495 | + } |
| 496 | + |
| 497 | + .hero-mark-rail--bottom::after { |
| 498 | + animation-delay: -3.6s; |
| 499 | + } |
| 500 | + } |
| 501 | + |
| 502 | + @keyframes hero-mark-float { |
| 503 | + from { |
| 504 | + translate: 0 -50%; |
| 505 | + rotate: -1deg; |
| 506 | + } |
| 507 | + |
| 508 | + to { |
| 509 | + translate: -0.4rem calc(-50% - 0.6rem); |
| 510 | + rotate: 1.25deg; |
| 511 | + } |
| 512 | + } |
| 513 | + |
| 514 | + @keyframes hero-mark-plane { |
450 | 515 | from { |
451 | | - transform: rotateX(9deg) rotateY(-15deg); |
| 516 | + transform: perspective(60rem) rotateY(-12deg) rotateZ(-5deg) translateX(0); |
452 | 517 | } |
453 | 518 |
|
454 | 519 | to { |
455 | | - transform: rotateX(9deg) rotateY(15deg); |
| 520 | + transform: perspective(60rem) rotateY(-9deg) rotateZ(-3.5deg) |
| 521 | + translateX(-0.6rem); |
456 | 522 | } |
457 | 523 | } |
458 | 524 |
|
459 | | - @keyframes hero-lattice-gossip { |
| 525 | + @keyframes hero-mark-signal { |
460 | 526 | 0%, |
461 | | - 8% { |
| 527 | + 10% { |
462 | 528 | opacity: 0; |
463 | | - transform: translateX(0); |
| 529 | + translate: 0; |
464 | 530 | } |
465 | 531 |
|
466 | | - 18%, |
| 532 | + 20%, |
467 | 533 | 72% { |
468 | 534 | opacity: 1; |
469 | 535 | } |
470 | 536 |
|
471 | | - 82%, |
| 537 | + 90%, |
472 | 538 | 100% { |
473 | 539 | opacity: 0; |
474 | | - transform: translateX(var(--edge-length, 0)); |
475 | | - } |
476 | | - } |
477 | | - |
478 | | - @media (prefers-reduced-motion: reduce) { |
479 | | - .hero-lattice-stage { |
480 | | - animation: none; |
481 | | - transform: rotateX(9deg) rotateY(-9deg); |
482 | | - } |
483 | | - |
484 | | - .hero-lattice-edge::after { |
485 | | - @apply opacity-100; |
486 | | - |
487 | | - animation: none; |
488 | | - transform: translateX(calc(var(--edge-length, 0px) / 2)); |
| 540 | + translate: 34vw; |
489 | 541 | } |
490 | 542 | } |
491 | 543 |
|
|
0 commit comments