﻿/* Hero component
   Presentation driven by the settings resolved in _Hero_Base.cshtml. Each
   setting maps to a class on the hero root. */

.hero {
    position: relative;
    display: flex;
    align-items: center;
    margin-bottom: 1.5rem;
    padding: 3rem 0;
    overflow: hidden;
}

/* A hero with no picture sits on a surface that follows the active theme.
   This was a fixed light panel before, which showed as a pale slab in dark
   mode because it ignored the theme entirely. */
.hero:not(.hero--has-bg) {
    background-color: var(--bs-tertiary-bg, #f8f9fa);
    color: var(--bs-body-color);
}

/* Height ------------------------------------------------------------------ */
.hero--h-auto { min-height: 0; }
.hero--h-medium { min-height: 400px; }
.hero--h-large { min-height: 600px; }
.hero--h-full { min-height: 100vh; }

/* Edges ------------------------------------------------------------------- */
.hero--edges-rounded { border-radius: var(--bs-border-radius-xl, 0.5rem); }
.hero--edges-square { border-radius: 0; }

/* Backdrop ----------------------------------------------------------------
   The picture and its overlay, behind the words. Kept as its own layer so the
   overlay can darken the image without touching the text on top of it. */
.hero__backdrop {
    position: absolute;
    inset: 0;
    z-index: 0;
    background-image: var(--hero-image);
    background-repeat: no-repeat;
    background-size: cover;
}

/* Which part of the picture survives the crop. */
.hero--focal-center .hero__backdrop { background-position: center center; }
.hero--focal-top .hero__backdrop { background-position: center top; }
.hero--focal-bottom .hero__backdrop { background-position: center bottom; }

/* Overlay strength, as a variable so the two shapes below can share it. */
.hero--overlay-none { --hero-scrim: 0; }
.hero--overlay-light { --hero-scrim: 0.25; }
.hero--overlay-medium { --hero-scrim: 0.45; }
.hero--overlay-dark { --hero-scrim: 0.65; }

.hero__backdrop::after {
    content: "";
    position: absolute;
    inset: 0;
    background-color: rgba(0, 0, 0, var(--hero-scrim, 0));
}

/* Heaviest where the words usually sit and clear at the top, so more of the
   picture shows through than an even scrim allows. */
.hero--scrim-gradient .hero__backdrop::after {
    background-color: transparent;
    background-image: linear-gradient(to top,
        rgba(0, 0, 0, var(--hero-scrim, 0)) 0%,
        rgba(0, 0, 0, calc(var(--hero-scrim, 0) * 0.55)) 45%,
        rgba(0, 0, 0, 0) 100%);
}

/* Movement ----------------------------------------------------------------
   Both act on the backdrop rather than the hero, so the words stay put. */

/* A long, slow push. Held at the end rather than looping, so a hero that has
   been on screen a while is not still creeping. */
@keyframes hero-ken-burns {
    from { transform: scale(1); }
    to { transform: scale(1.15); }
}

.hero--kenburns .hero__backdrop,
.hero--kenburns .hero__media img {
    animation: hero-ken-burns 20s ease-out forwards;
}

/* The picture stays with the viewport while the page moves over it. Browsers
   on touch screens do not honour this, and it costs them scroll performance
   to try, so it is only asked for on larger screens. */
@media (min-width: 992px) {
    .hero--parallax .hero__backdrop {
        background-attachment: fixed;
    }
}

/* Content ----------------------------------------------------------------- */
.hero__inner {
    position: relative;
    z-index: 1;
    width: 100%;
    padding: 0 1.5rem;
}

.hero__content {
    width: 100%;
}

.hero--align-left { text-align: left; }
.hero--align-center { text-align: center; }
.hero--align-right { text-align: right; }

.hero--align-left .hero__content { margin-right: auto; }
.hero--align-right .hero__content { margin-left: auto; }

.hero--align-center .hero__content {
    margin-left: auto;
    margin-right: auto;
}

/* Width is only constrained once there is room for it to mean anything.
   Below md every hero runs the full width of its container. */
@media (min-width: 768px) {
    .hero--w-narrow .hero__content { max-width: 50%; }
    .hero--w-medium .hero__content { max-width: 66.6667%; }
    .hero--w-wide .hero__content { max-width: 83.3333%; }
    .hero--w-full .hero__content { max-width: 100%; }
}

/* Split -------------------------------------------------------------------
   The picture takes half the hero rather than sitting behind the words, so
   nothing needs darkening and the text keeps the page's own colors. */
.hero--split {
    padding: 0;
}

.hero--split .hero__inner {
    display: flex;
    align-items: stretch;
    padding: 0;
}

.hero--split .hero__content {
    flex: 1 1 50%;
    align-self: center;
    padding: 3rem;
    /* The split already decides how wide the words are. */
    max-width: none;
}

.hero--split .hero__media {
    flex: 1 1 50%;
    min-height: 320px;
}

.hero--split .hero__media img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.hero--imageside-left .hero__inner {
    flex-direction: row-reverse;
}

/* The focal point applies to the image itself here, not to a backdrop. */
.hero--split.hero--focal-center .hero__media img { object-position: center; }
.hero--split.hero--focal-top .hero__media img { object-position: top; }
.hero--split.hero--focal-bottom .hero__media img { object-position: bottom; }

/* Side by side needs room. Below md the two stack, with the picture following
   the words unless the editor asked for it first. */
@media (max-width: 767.98px) {
    .hero--split .hero__inner { flex-direction: column; }
    .hero--imageside-left .hero__inner { flex-direction: column-reverse; }
    .hero--split .hero__content { padding: 2rem 1.5rem; }
    .hero--split .hero__media { min-height: 220px; }
}

/* Text -------------------------------------------------------------------- */
.hero--text-light { color: #fff; }
.hero--text-dark { color: var(--bs-body-color); }

/* The kicker above the headline. Small, spaced and upper case, which is how
   this line reads as a label rather than as the first line of the title. */
.hero__eyebrow {
    margin-bottom: 0.5rem;
    font-size: 0.875rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    /* Slightly back from the title without losing contrast against either a
       darkened photograph or the themed surface. */
    opacity: 0.85;
}

.hero__title {
    margin-bottom: 1rem;
    font-weight: 700;
    /* Scales with the viewport rather than being one of two fixed display
       sizes, which is what the two templates used to disagree about. The
       heading level setting changes the tag, not the size, so a hero under a
       page title still looks like a hero. */
    font-size: clamp(2rem, 4vw, 3.5rem);
}

.hero__text {
    font-size: 1.25rem;
}

/* Rich text arrives with its own trailing margin, which would push the button
   further away than intended. */
.hero__text > :last-child {
    margin-bottom: 0;
}

/* Buttons sit in a row that wraps, and follow the content's alignment. */
.hero__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin-top: 1.5rem;
}

.hero--align-center .hero__actions { justify-content: center; }
.hero--align-right .hero__actions { justify-content: flex-end; }

/* Movement is the visitor's call, not the editor's. */
@media (prefers-reduced-motion: reduce) {
    .hero--kenburns .hero__backdrop,
    .hero--kenburns .hero__media img {
        animation: none;
    }

    .hero--parallax .hero__backdrop {
        background-attachment: scroll;
    }
}

@media (max-width: 767.98px) {
    .hero {
        padding: 2rem 0;
    }

    .hero__text {
        font-size: 1.05rem;
    }
}

/* Styles ------------------------------------------------------------------
   The look, as opposed to the shape. Every rule below changes only how the
   hero is painted, never what the renderer emits, which is what keeps these a
   setting rather than a template. */

/* Panel. The words sit on their own ground rather than straight on the
   picture, which holds them together on a busy photograph where a scrim alone
   leaves the text floating. */
.hero--style-panel .hero__content {
    padding: 2rem;
    border-radius: var(--bs-border-radius-xl, 0.5rem);
    background-color: rgba(0, 0, 0, 0.45);
}

/* Without a picture there is nothing to sit over, so the panel follows the
   theme instead of being a dark box on a light page. */
.hero:not(.hero--has-bg).hero--style-panel .hero__content {
    background-color: var(--bs-body-bg, #fff);
    box-shadow: 0 0.5rem 1.5rem rgba(0, 0, 0, 0.12);
}

.hero--style-panel.hero--align-center .hero__content {
    margin-inline: auto;
}

/* Banner. The eyebrow runs into the title on one line, with a solid block
   behind the title. Built from the eyebrow and title fields that already
   exist rather than from new markup, so the header stays a block and its two
   children go inline to flow onto one line. */
.hero--style-banner .hero__eyebrow,
.hero--style-banner .hero__title {
    display: inline;
    margin: 0;
    font-size: clamp(2rem, 4vw, 3.5rem);
    font-weight: 700;
    letter-spacing: normal;
    line-height: 1.45;
    text-transform: uppercase;
}

.hero--style-banner .hero__eyebrow {
    opacity: 1;
}

/* A space between the two, which the markup does not provide because they are
   separate elements. */
.hero--style-banner .hero__eyebrow::after {
    content: " ";
    white-space: pre;
}

/* Cloned so a title that wraps keeps the block on every line rather than one
   box stretched behind all of them. */
.hero--style-banner .hero__title {
    box-decoration-break: clone;
    -webkit-box-decoration-break: clone;
    padding: 0.05em 0.35em;
    background-color: var(--bs-primary, #0d6efd);
    color: #fff;
}

.hero--style-banner .hero__text {
    margin-top: 1.5rem;
}

/* Two columns ------------------------------------------------------------
   The second column is the rest of the same rich text, flowed by the browser
   rather than stored separately. An author writes paragraphs as normal and
   they balance across the columns, which is why this works with any number of
   them rather than exactly two. */
.hero--columns .hero__content {
    column-gap: 2.5rem;
}

.hero--columns.hero--cols-2 .hero__content { column-count: 2; }
.hero--columns.hero--cols-3 .hero__content { column-count: 3; }

.hero--col-rule .hero__content {
    column-rule: 1px solid currentColor;
}

/* Ruled columns read as heavier than they are, because the rule takes the
   text color at full strength. */
.hero--col-rule.hero--text-light .hero__content {
    column-rule-color: rgba(255, 255, 255, 0.35);
}

.hero--col-rule:not(.hero--text-light) .hero__content {
    column-rule-color: rgba(0, 0, 0, 0.15);
}

/* A paragraph broken across a column boundary is much harder to read than an
   unbalanced pair of columns. */
.hero--columns .hero__text p,
.hero--columns .hero__eyebrow {
    break-inside: avoid;
}

/* The title either spans the whole width or joins the flow at the head of
   the first column. Buttons always span: a call to action stranded at the
   foot of one column is a call to action nobody sees. */
.hero--title-span .hero__eyebrow,
.hero--title-span .hero__title {
    column-span: all;
}

.hero--columns .hero__actions {
    column-span: all;
}

/* A heading that flows has to stay with the paragraph under it. */
.hero--columns:not(.hero--title-span) .hero__title {
    break-after: avoid;
}

/* Columns need width. Below md there is none to give, so they stack. */
@media (max-width: 767.98px) {
    .hero--columns.hero--cols-2 .hero__content,
    .hero--columns.hero--cols-3 .hero__content {
        column-count: 1;
    }
}

/* Three is too many on a tablet. */
@media (min-width: 768px) and (max-width: 991.98px) {
    .hero--columns.hero--cols-3 .hero__content {
        column-count: 2;
    }
}

/* Button corners ---------------------------------------------------------
   Its own setting rather than a style value, because square buttons suit any
   of the styles and a style is one choice from a list. */
.hero--btn-square .hero__cta {
    border-radius: 0;
}

/* Display ----------------------------------------------------------------
   The masthead look: the eyebrow carries the heavy half of the name and the
   title the light half beneath it. Two weights at display size out of the two
   fields that already exist, rather than a line break inside one of them. */
.hero--style-display .hero__eyebrow {
    margin-bottom: 0;
    font-size: clamp(2rem, 4vw, 3.5rem);
    font-weight: 800;
    letter-spacing: -0.01em;
    line-height: 1.05;
    text-transform: uppercase;
    opacity: 1;
}

.hero--style-display .hero__title {
    font-weight: 300;
    letter-spacing: -0.01em;
    line-height: 1.05;
    text-transform: uppercase;
}

/* The two lines are one name, so they sit tight together and the space goes
   under the pair. */
.hero--style-display .hero__title {
    margin-bottom: 1.25rem;
}

/* Action beside ----------------------------------------------------------
   Words on one side, buttons on the other and vertically centred. For a short
   band that is a statement and a single call to action, where buttons
   underneath would waste the height. */
@media (min-width: 768px) {
    .hero--style-actionBeside .hero__content {
        display: flex;
        align-items: center;
        gap: 2.5rem;
    }

    /* The words take the room that is going; the buttons take what they need. */
    .hero--style-actionBeside .hero__eyebrow,
    .hero--style-actionBeside .hero__title,
    .hero--style-actionBeside .hero__text {
        flex: 1 1 auto;
        margin-bottom: 0;
    }

    .hero--style-actionBeside .hero__actions {
        flex: 0 0 auto;
        margin-top: 0;
    }

    /* A title and a line of text need to stay together on the left rather
       than becoming two flex columns of their own. */
    .hero--style-actionBeside .hero__content {
        flex-wrap: wrap;
    }

    .hero--style-actionBeside .hero__title {
        flex-basis: 100%;
    }

    .hero--style-actionBeside .hero__text {
        flex: 1 1 60%;
    }
}

/* Full bleed ---------------------------------------------------------------
   The picture and any scrim run to the edges of the window, which is the point
   of a full bleed page. The words do not: they keep the band the rest of the
   site lines up with, so a heading does not start in the corner of the screen.
   The inner already carries its own side padding. */
.page-full .hero__inner {
    max-width: var(--cms-band);
    margin-inline: auto;
    /* The same gutter the header uses, so a heading lines up with the brand
       rather than sitting a few pixels inside it. */
    padding-inline: 0.75rem;
}

/* A chosen button color ---------------------------------------------------
   The one setting that arrives as a custom property rather than a class,
   because its value is not from a list these rules could be written against.
   _Hero_Base.cshtml sets --hero-button-color and --hero-button-text on the
   root, through ResolvedSettings.Color, so only six hex digits ever land in
   that style attribute.

   Only the main button takes it. An outlined or plain button beside it is
   there to be quieter, and painting both would remove the difference. */

.hero--btn-custom .hero__btn--main,
.hero--btn-custom .hero__btn--main:hover,
.hero--btn-custom .hero__btn--main:focus,
.hero--btn-custom .hero__btn--main:active {
    background-color: var(--hero-button-color);
    border-color: var(--hero-button-color);
    /* Black or white, worked out from the color rather than guessed, so a
       pale brand color does not end up with white words on it. */
    color: var(--hero-button-text);
}

.hero--btn-custom .hero__btn--main:hover,
.hero--btn-custom .hero__btn--main:focus {
    /* The same color, a shade down: a second color to configure for a hover
       state is a setting nobody wants to fill in. */
    filter: brightness(0.92);
}

.hero--btn-custom .hero__btn--main:focus-visible {
    box-shadow: 0 0 0 .25rem rgba(var(--bs-body-color-rgb, 33, 37, 41), .25);
}

/* Showcase ----------------------------------------------------------------
   A backdrop behind everything and a second picture in front of it, beside
   the words. It borrows the split's side-by-side layout and changes two
   things about it.

   The split's picture is a scene, cropped to fill its half. A showcase's is a
   thing - a book, a product, a device - so it is shown whole, and the band
   keeps its padding so the backdrop reads as a background rather than as the
   picture itself. */
.hero--showcase {
    padding-block: 4rem;
}

.hero--showcase .hero__inner {
    align-items: center;
}

.hero--showcase .hero__content {
    padding-block: 1rem;
}

.hero--showcase .hero__media {
    /* The split gives its picture a floor to fill. This one is as tall as it
       needs to be. */
    min-height: 0;
    align-self: center;
}

.hero--showcase .hero__media img {
    /* Whole, not cropped: a cover with its top sliced off is not a cover. */
    object-fit: contain;
    height: auto;
    max-height: 28rem;
    margin-inline: auto;
}

/* The focal point belongs to the backdrop here, not to the feature, so the
   split's object-position rules must not reach it. */
.hero--showcase.hero--focal-center .hero__media img,
.hero--showcase.hero--focal-top .hero__media img,
.hero--showcase.hero--focal-bottom .hero__media img {
    object-position: center;
}

@media (max-width: 767.98px) {
    .hero--showcase {
        padding-block: 2.5rem;
    }

    .hero--showcase .hero__media {
        min-height: 0;
    }

    .hero--showcase .hero__media img {
        max-height: 20rem;
    }
}
