/* --- Hero --------------------------------------------------------------------- A full-width band in the brand gradient with a faint dot pattern on top. The page content sits in a centred column (.content in MainLayout), so the band breaks out of it: 100vw wide, pulled left by the column's offset. body clips the few pixels of scrollbar this adds (see app.css). The negative top margin cancels the column's top padding, so the band meets the header without a strip of page background in between. The pattern is an inline SVG in a data: URL -- no request, nothing from another host. White dots at 12% opacity: visible as texture, too faint to cost the white text any contrast. */ .hero { width: 100vw; margin: calc(-1 * var(--space-4)) 0 var(--space-5) calc(50% - 50vw); background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24'%3E%3Ccircle cx='3' cy='3' r='1.5' fill='%23fff' fill-opacity='.12'/%3E%3C/svg%3E"), var(--gradient-brand); color: var(--color-on-header); } /* The inside follows the page frame again, so the hero text lines up with the tiles and lists below. Stacked on a phone; from tablet width the next-event card moves beside the text. */ .hero-inner { box-sizing: border-box; max-width: var(--content-width); margin: 0 auto; padding: var(--space-6) 1.25rem; display: grid; gap: var(--space-5); align-items: center; } @media (min-width: 48rem) { .hero-inner { grid-template-columns: minmax(0, 1fr) minmax(16rem, 22rem); } } /* On the gradient everything is white: the global heading colour is a blue that would vanish here. */ .hero h1 { color: var(--color-on-header); } /* The intro is editor Markdown, rendered without scope attributes, so it is reached through ::deep. Slightly larger than body text, as a lead. Links stay white and underlined: the blue link colour would be unreadable on the gradient. */ .hero-intro ::deep p { font-size: 1.15rem; } .hero-intro ::deep a, .hero-intro ::deep a:hover { color: var(--color-on-header); } .hero-actions { display: flex; flex-wrap: wrap; gap: var(--space-3); margin: var(--space-4) 0 0; } /* The hero's buttons, adapted to the dark gradient: the primary turns light (a filled blue would melt into the blue end), the secondary becomes a white outline with the same translucent wash as the header menu on hover. The focus ring turns white for the same reason. */ .hero .btn-primary { background: var(--color-button-light); border-color: var(--color-button-light); color: var(--color-on-button-light); } .hero .btn-primary:hover { background: var(--color-button-light-hover); border-color: var(--color-button-light-hover); color: var(--color-on-button-light); } .hero .btn-secondary { border-color: var(--color-on-header); color: var(--color-on-header); } .hero .btn-secondary:hover { background: var(--color-nav-hover); color: var(--color-on-header); } .hero .btn:focus-visible { outline-color: var(--color-on-header); } /* --- Next event --------------------------------------------------------------- A card on the gradient: the regular card surface, so its text uses the normal tokens and adapts to dark mode by itself. The whole card is one link to the events page. */ .next-event { display: block; padding: var(--space-4); border-radius: var(--radius); background: var(--color-bg); box-shadow: var(--shadow-lg); color: var(--color-text); text-decoration: none; transition: box-shadow var(--transition); } .next-event:hover { color: var(--color-text); box-shadow: var(--shadow-hover), var(--shadow-lg); } /* The ring sits outside the card, on the gradient, so it is white like the hero's button rings. */ .next-event:focus-visible { outline: 3px solid var(--color-on-header); outline-offset: 3px; } .next-event-label { display: block; margin-bottom: var(--space-3); color: var(--color-text-soft); font-size: 0.85rem; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; } .next-event-row { display: flex; gap: var(--space-3); align-items: flex-start; } /* The calendar sheet: a blue band with the month over a large day number. The band uses the button blue, which keeps white text at >= 5.5:1 in both schemes (the green accent would fall below AA for text this small). */ .calendar-sheet { flex-shrink: 0; display: flex; flex-direction: column; width: 4rem; overflow: hidden; border: 1px solid var(--color-border); border-radius: var(--radius-sm); background: var(--color-bg); text-align: center; } .calendar-month { padding: 0.1rem 0; background: var(--color-button); color: var(--color-on-button); font-size: 0.8rem; font-weight: 700; text-transform: uppercase; } .calendar-day { padding: var(--space-1) 0; color: var(--color-heading); font-size: 1.75rem; font-weight: var(--font-weight-heading); line-height: 1.2; } .next-event-details { min-width: 0; /* lets a long title wrap instead of widening the card */ } .next-event-title { display: block; color: var(--color-brand); font-size: 1.15rem; font-weight: 700; line-height: 1.3; } .next-event-location { display: flex; align-items: center; gap: var(--space-1); margin-top: var(--space-1); color: var(--color-text-soft); font-size: 0.9rem; } /* --- Tiles -------------------------------------------------------------------- One card per header page. auto-fill with a minimum width gives as many columns as fit (one on a phone) without breakpoints. Hover = stronger shadow and a blue edge, nothing moves. */ .home-tiles ul { display: grid; grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr)); gap: var(--space-3); margin: 0; padding: 0; list-style: none; } .tile-link { box-sizing: border-box; display: grid; grid-template-columns: auto minmax(0, 1fr); column-gap: var(--space-3); align-items: center; height: 100%; padding: var(--space-3) var(--space-4); border: 1px solid transparent; border-radius: var(--radius); background: var(--color-bg); box-shadow: var(--shadow); color: var(--color-text); text-decoration: none; transition: box-shadow var(--transition), border-color var(--transition); } .tile-link:hover { border-color: var(--color-brand); box-shadow: var(--shadow-hover); color: var(--color-text); } .tile-link:focus-visible { outline: 3px solid var(--color-focus); outline-offset: 2px; } /* The icon in a soft round tint; it spans both rows, so title and text line up beside it whether there is a text or not. */ .tile-icon { grid-row: span 2; display: grid; place-items: center; width: 3rem; height: 3rem; border-radius: 50%; background: var(--color-brand-tint); color: var(--color-brand); } .tile-title { color: var(--color-brand); font-size: 1.1rem; font-weight: 700; } .tile-text { color: var(--color-text-soft); font-size: 0.9rem; line-height: 1.45; } /* --- Embeds ------------------------------------------------------------------- The blocks the home page opts into (posts, events) sit side by side from desktop width, so the start page shows both without a long scroll. One column below. */ @media (min-width: 64rem) { .home-embeds { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-5); align-items: start; } }