@import url('https://fonts.googleapis.com/css2?family=Bricolage+Grotesque:wght@700;800&family=DM+Sans:wght@400;500;600;700&display=swap');

html, body {
    font-family: 'DM Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
}

/* Grass focus ring on keyboard navigation (design-system foundations: accent = focus). */
:focus-visible {
    outline: 2px solid #89CC4E;
    outline-offset: 2px;
}

h1:focus {
    outline: none;
}

/* Form validation states use the design-system status colours: darkened Grass
   for valid, brand error red for invalid. */
.valid.modified:not([type=checkbox]) {
    outline: 1px solid #4F7A28;
}

.invalid {
    outline: 1px solid #D2362C;
}

.validation-message {
    color: #D2362C;
}

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

    .blazor-error-boundary::after {
        content: "An error has occurred."
    }


/* One installation row inside a FormSection: a bordered panel with a tinted, numbered
   header. A divider between rows was not enough — a row is several steps tall and looks
   much like its neighbour, so the list read as one long block of fields. */
.keima-installation-row {
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: var(--mud-default-borderradius);
    margin-bottom: 16px;
}

.keima-installation-row-header {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 12px;
    background-color: var(--mud-palette-background-gray);
    border-bottom: 1px solid var(--mud-palette-lines-default);
}

/* The address or meter id the row currently holds. It gives way before the label does,
   since it is the part that can be read from the fields below. */
.keima-installation-row-summary {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--mud-palette-text-secondary);
}

.keima-installation-row-body {
    padding: 0 12px 8px;
}


/* The "private or business" choice: two cards that say what each option will ask of the
   participant. The options carry the weight themselves - what they replaced was a filled
   banner above them telling the participant to look down at them, which shouted at a form
   that needs to look trustworthy.

   MudRadio puts its Class on the input-control wrapper rather than on the label, so the
   card is that wrapper and the label inside it is only stretched to fill it. */
.keima-choice-group .mud-radio-group {
    display: flex;
    width: 100%;
    gap: 12px;
}

/* Half the row each, so the pair fills the form's width and reads as one control rather
   than as two boxes that happen to sit side by side. The class is qualified by the group
   because MudBlazor pins its own flex: none on these wrappers. */
.keima-choice-group .keima-choice-tile {
    flex: 1 1 0;
    min-width: 0;
    margin: 0;
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: var(--mud-default-borderradius);
    transition: border-color 150ms, background-color 150ms;
}

/* Side by side is too tight for two cards on a phone. */
@media (max-width: 599px) {
    .keima-choice-group .mud-radio-group {
        flex-direction: column;
    }
}

.keima-choice-tile .mud-radio {
    position: relative;
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 16px;
    align-items: center;
}

/* MudRadio's content sits in a <p> beside the (hidden) circle; without this it is only
   as wide as its text and the card's tick drifts in from the right edge. */
.keima-choice-tile .mud-radio > .mud-typography {
    width: 100%;
}

/* The card's own border and tint say which option is picked, so the radio's circle would
   be a second marker for the same thing. It stays in the DOM for the keyboard and for
   screen readers. */
.keima-choice-tile .mud-radio .mud-icon-button {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    opacity: 0;
    pointer-events: none;
}

.keima-choice-group .keima-choice-tile:hover {
    border-color: var(--mud-palette-primary);
}

/* Until a choice is made both cards are outlined in the brand colour, which is the whole
   attention-drawing device. The picked one then takes a heavier border and a faint tint,
   and the other falls back to a quiet grey. */
.keima-choice-group-unset .keima-choice-tile {
    border-color: var(--mud-palette-primary);
}

.keima-choice-group .keima-choice-tile-selected {
    border-color: var(--mud-palette-primary);
    border-width: 2px;
    background-color: var(--mud-palette-primary-hover);
}

/* The 2px border on the picked card would otherwise shift its content by a pixel. */
.keima-choice-tile-selected .mud-radio {
    padding: 15px;
}

/* Spans, because MudRadio wraps its content in a <p> and a <p> may not contain divs.
   The icon sits to the left of the wording rather than above it, which keeps the pair of
   cards short enough to read as one line of the form. */
.keima-choice-card {
    display: flex;
    align-items: center;
    gap: 12px;
}

.keima-choice-card-icon {
    flex: 0 0 auto;
    color: var(--mud-palette-primary);
}

.keima-choice-card-text {
    display: block;
    min-width: 0;
}

.keima-choice-card-title {
    display: flex;
    align-items: center;
    gap: 6px;
    font-weight: 600;
}

.keima-choice-card-description {
    display: block;
    margin-top: 2px;
    font-size: 0.8125rem;
    line-height: 1.35;
    color: var(--mud-palette-text-secondary);
}


/* What is left to do before the form can be sent, in the warning colour: it is not an
   error - nothing is wrong with what has been entered - but it is the thing standing
   between the participant and sending the form, so it should catch the eye. The fields
   themselves still carry their own errors. */
.keima-submit-blockers {
    padding: 16px;
    border: 1px solid var(--mud-palette-warning);
    border-radius: var(--mud-default-borderradius);
    background-color: rgba(var(--mud-palette-warning-rgb), 0.08);
    color: var(--mud-palette-warning-darken);
}

.keima-submit-blockers ul {
    margin: 8px 0 0;
    padding-left: 1.5rem;
}

.keima-submit-blockers li {
    padding: 2px 0;
    font-size: 0.875rem;
    line-height: 1.4;
}


/* The block introducing the group above the signup form. Everything shares the card's
   left edge - the earlier centred version left the headings on one axis and the
   description on another, which read as unfinished - and it is kept short so the form
   itself is close to the top of the page. */
.keima-masthead-heading {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
}

/* Bounded on both axes: group logos arrive at whatever size and shape they were uploaded
   at, and the box they fit inside keeps a wide one from dwarfing the title. It gives way
   first when there is no room for both.
   The height allowance is what a square logo gets to use - Sydstevns Energi's is 161x161,
   and a lower cap threw away most of it - while a wide wordmark runs out of width long
   before it reaches that height. */
.keima-masthead-logo {
    flex: 0 1 auto;
    width: auto;
    max-width: 180px;
    max-height: 96px;
    /* Square-cropped logos sit next to rounded cards and chips, so they are rounded to match. */
    border-radius: 4px;
}

/* Group names run long - "Bliv andelshaver i Ærø Borgerenergifællesskab A.M.B.A." - so the
   size gives way on narrow screens. */
.keima-masthead-title {
    margin: 0;
    font-size: clamp(1.375rem, 3vw, 1.75rem);
    font-weight: 600;
    line-height: 1.2;
    color: var(--mud-palette-primary);
}

/* The group's own one-line pitch. It carries more weight than the description below it -
   larger, darker, and in the page's own text colour - because the two were otherwise the
   same grey paragraph twice over. */
.keima-masthead-subtitle {
    margin: 6px 0 0;
    font-size: 1.125rem;
    font-weight: 500;
    line-height: 1.35;
    color: var(--mud-palette-text-primary);
}

.keima-masthead-description {
    max-width: 62ch;
    margin: 16px 0 0;
    font-size: 0.9375rem;
    line-height: 1.6;
    color: var(--mud-palette-text-secondary);
    /* The stored copy carries its own paragraph breaks. */
    white-space: pre-line;
}

.keima-masthead-postal-codes {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin-top: 16px;
}

.keima-masthead-postal-codes-label {
    margin-right: 4px;
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--mud-palette-text-secondary);
}

/* Tinted in the brand colour rather than outlined in grey: this is the line a reader
   checks themselves against, so it should be the one thing in the block that catches the
   eye. */
.keima-postal-code {
    padding: 2px 10px;
    border: 1px solid rgba(var(--mud-palette-primary-rgb), 0.4);
    border-radius: 999px;
    background-color: rgba(var(--mud-palette-primary-rgb), 0.08);
    font-size: 0.8125rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    color: var(--mud-palette-primary);
}

/* Side by side is too tight for a logo and a long group name on a phone. */
@media (max-width: 599px) {
    .keima-masthead-heading {
        flex-direction: column-reverse;
        align-items: flex-start;
    }
}


/* An aside on the form: something worth knowing before filling a section in. Tinted in the
   theme's info blue - enough to be read as a note rather than as more form furniture, and
   distinct from both the brand green around it and the warning colour that means something
   is actually outstanding. */
.keima-note {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 12px 16px;
    border: 1px solid rgba(var(--mud-palette-info-rgb), 0.4);
    border-radius: var(--mud-default-borderradius);
    background-color: rgba(var(--mud-palette-info-rgb), 0.08);
    color: var(--mud-palette-text-primary);
    font-size: 0.875rem;
    line-height: 1.5;
}

.keima-note-icon {
    flex: 0 0 auto;
    margin-top: 2px;
    color: var(--mud-palette-info);
}


/* The add-a-billing-group button, shown inside a sentence that refers to it. Sized to the
   text rather than to the real button: at full size it would push the lines around it
   apart. line-height: 0 keeps the line box the text's own height. */
.keima-note-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    margin: 0 2px;
    border-radius: 50%;
    background-color: var(--mud-palette-primary);
    color: var(--mud-palette-primary-text);
    line-height: 1;
    vertical-align: middle;
}

.keima-note-button .mud-icon-root {
    width: 13px;
    height: 13px;
    font-size: 13px;
}


/* MudBlazor's card header pads all four sides equally, which stacked with the content's own
   padding left a gap below the title far wider than any other gap in the card. */
.keima-form-section .mud-card-header {
    padding-bottom: 8px;
}

/* MudBlazor pulls a card header's actions 8px up and to the right, which puts the button
   outside the padding every other thing in the card lines up with. */
.keima-form-section .mud-card-header-actions {
    margin-top: 0;
    margin-right: 0;
    margin-inline-end: 0;
}


/* The line between a block's billing details and the addresses they pay for.
   width: auto overrides .mud-divider-fullwidth, which pins width: 100%. With a fixed width
   the mx-n4 bleed only shifts the line left instead of widening it, leaving it short on the
   right; with auto width the negative margins do what they read like. The colour is lifted
   because MudBlazor's default divider is fainter than every other line on the page. */
.keima-section-divider {
    width: auto;
    border-color: var(--mud-palette-lines-default);
}


/* One document to accept. Grey until it is ticked, green once it is: with several documents
   in a row, what is left to accept should be visible without reading each checkbox.

   Neither state uses --mud-palette-background-gray, which in this theme is a pale green
   (Growth Sunken) - as a resting state it read as already accepted. */
.keima-term {
    display: flex;
    align-items: center;
    padding: 4px 12px;
    margin-bottom: 6px;
    border-radius: var(--mud-default-borderradius);
    background-color: rgba(0, 0, 0, 0.05);
    transition: background-color 150ms;
}

.keima-term-accepted {
    background-color: var(--mud-palette-secondary);
}

/* The checkbox brings its own padding on top of the row's. */
.keima-term .mud-checkbox {
    margin-left: -8px;
}

@media (prefers-color-scheme: dark) {
    .keima-term {
        background-color: rgba(255, 255, 255, 0.07);
    }
}
