/*
   Autonomycs MY portal - app-specific styles only.

   The design tokens, the shared primitives (.btn, .card, .row, .field, .badge, ...) and the Radzen
   brand mapping live in Autonomycs.Ui.Web (_content/Autonomycs.Ui.Web/css/tokens.css + ui.css),
   linked BEFORE this file in index.html. What remains here is this app's own chrome (shell,
   sidebar, top bar) and its screen-specific families (results, benefits, profile, welcome, ...).

   Layout is hand-written rather than Radzen: the artboards are specific enough that fighting a
   component's DOM would cost more than writing the markup.
*/

/* -------------------------------------------------- shell */
.shell {
    display: flex;
    height: 100vh;
    align-items: stretch;
    width: 100%;
    overflow: hidden;
}

.shell__main {
    flex: 1;
    min-width: 0;
    max-width: 100%;
    overflow-x: hidden;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
}

.shell__body {
    flex: 1;
    width: 100%;
    min-width: 0;
    padding: 36px 44px 64px;
}

/* -------------------------------------------------- sidebar */
.sidebar {
    width: var(--sidebar-width);
    flex: none;
    background: var(--brand);
    color: #fff;
    padding: 28px 20px 24px;
    display: flex;
    flex-direction: column;
    gap: 28px;
    height: 100%;
    overflow-y: auto;
}

.sidebar__brand {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 0 8px;
}

/* img covers the pre-runtime splash in index.html, svg the inline BrandMark component. */
.sidebar__brand img,
.sidebar__brand svg {
    width: 34px;
    height: auto;
    display: block;
    flex: none;
}

.sidebar__wordmark {
    font: 500 19px/1 var(--font);
    color: #fff;
    letter-spacing: -.01em;
}

.sidebar__nav {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

/* The member, pinned to the sidebar's bottom edge, doubling as the link to "Mijn gegevens". */
.sidebar__identity {
    margin-top: auto;
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 8px;
    border-radius: 14px;
    color: #fff;
}

.sidebar__identity:hover {
    background: rgba(255, 255, 255, .09);
    color: #fff;
}

.sidebar__identity--active {
    background: rgba(255, 255, 255, .16);
}

/* min-width:0 is what lets the name ellipsize instead of widening the drawer. */
.sidebar__identity-text {
    display: flex;
    flex-direction: column;
    line-height: 1.25;
    min-width: 0;
}

.sidebar__identity-name {
    font: 500 16px/1.2 var(--font);
    color: #fff;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.sidebar__identity-meta {
    font: 400 13px/1.3 var(--font);
    color: rgba(255, 255, 255, .72);
}

.navlink {
    position: relative;
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 14px 16px;
    border: 0;
    background: transparent;
    border-radius: 14px;
    cursor: pointer;
    text-align: left;
    color: #fff;
    font: 500 17px/1.2 var(--font);
    width: 100%;
}

.navlink:hover {
    background: rgba(255, 255, 255, .09);
    color: #fff;
}

.navlink--active {
    background: rgba(255, 255, 255, .16);
}

.navlink svg {
    flex: none;
    opacity: .92;
}

/* -------------------------------------------------- mobile drawer
   Hidden above the breakpoint, where the sidebar is simply always there. */
.menutoggle {
    display: none;
    border: 1px solid var(--hairline-strong);
    background: transparent;
    color: var(--brand);
    border-radius: var(--radius-control);
    padding: 8px;
    cursor: pointer;
    align-items: center;
    justify-content: center;
}

.menutoggle:hover {
    background: var(--canvas);
}

.sidebar-backdrop {
    display: none;
}

/* -------------------------------------------------- top bar */
.topbar {
    position: sticky;
    top: 0;
    z-index: 10;
    flex: none;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 24px;
    padding: 20px 44px;
    background: #fff;
    border-bottom: 1px solid var(--hairline);
}

.topbar__right {
    display: flex;
    align-items: center;
    gap: 20px;

    /* Pushes the identity block to the right regardless of whether the menu toggle is showing. */
    margin-left: auto;
}

.identity__avatar {
    width: 42px;
    height: 42px;
    border-radius: 50%;
    background: var(--olive);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font: 500 16px/1 var(--font);
    flex: none;
}

.identity__signout {
    display: inline-flex;
    align-items: center;
    border: 1px solid var(--hairline-strong);
    background: transparent;
    color: var(--brand);
    padding: 9px 14px;
    border-radius: var(--radius-control);
    font: 500 14px/1 var(--font);
    cursor: pointer;
}

/* Text on desktop, icon on mobile; the swap lives in the 560px block below. */
.identity__signout-icon {
    display: none;
}

.identity__signout:hover {
    background: var(--canvas);
}

/* Recent-documents list on the home screen. A document with no URL yet is shown greyed rather than
   as a link that goes nowhere. */
.doclink {
    font: 500 17px/1.3 var(--font);
}

.doclink--pending {
    color: var(--muted);
}

.doclink--pending em {
    font-style: normal;
    font-weight: 400;
    font-size: 15px;
}

/* The weekday/day/month chip on the left of a home row. */
.datechip {
    width: 66px;
    flex: none;
    text-align: center;
    background: var(--canvas);
    color: var(--ink);
    border-radius: var(--radius-control);
    padding: 6px 0;
}

.datechip--next {
    background: var(--brand);
    color: #fff;
}

.datechip__day {
    display: block;
    font: 500 22px/1 var(--font);
}

.datechip__weekday,
.datechip__month {
    display: block;
    font: 400 13px/1.4 var(--font);
    color: var(--muted);
}

.datechip--next .datechip__weekday,
.datechip--next .datechip__month {
    color: inherit;
    opacity: .8;
}

.sessionrow--cancelled .row__title,
.sessionrow--cancelled .row__meta {
    color: var(--muted);
}

.sessionrow--cancelled .dot {
    opacity: .45;
}

/* -------------------------------------------------- results screen */

/* The event strip (.resultstrip, .resultcard), the measure item rows (.measureitem) and the
   per-device results table (.devicecard__head, .devicetable, .resultrow, .deviceimage) that used to
   sit here are the design system's now - ui.css, MeasurementValues and SessionDeviceResults -
   because the admin's member Analyse is laid out the same way and draws the same thing, and the two
   must not drift. Only this page's own chrome stays.

   The measurement image. A sized box so a missing or slow image cannot reflow the card, and
   object-fit keeps arbitrary uploads presentable. */
.resultimage {
    width: 160px;
    height: 160px;
    object-fit: cover;
    border-radius: 14px;
    border: 1px solid var(--border);
    margin-bottom: 18px;
}

/* -------------------------------------------------- consent page */
.consenthead {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px 24px;
    padding-bottom: 20px;
    border-bottom: 1px solid var(--card-border);
    margin-bottom: 20px;
}

/* Server-authored HTML: give its raw tags the page's rhythm without styling each one. */

/* -------------------------------------------------- profile form */
.profilehead {
    display: flex;
    align-items: center;
    gap: 22px;
    padding-bottom: 26px;
    border-bottom: 1px solid var(--card-border);
    margin-bottom: 26px;
    flex-wrap: wrap;
}

.profilehead__avatar {
    width: 74px;
    height: 74px;
    border-radius: 50%;
    object-fit: cover;
    flex: none;
}

.profilehead__avatar--initials {
    background: var(--olive);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font: 500 26px/1 var(--font);
}

.profilehead__name {
    margin: 0;
    font: 500 22px/1.2 var(--font);
}

.profilegrid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(232px, 1fr));
    gap: 22px;
}

.field--wide {
    grid-column: 1 / -1;
}

.field__locknote {
    font: 400 14px/1 var(--font);
    color: var(--muted);
    font-style: normal;
    margin-left: 8px;
}

.profilefoot {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 20px;
    padding-top: 22px;
    border-top: 1px solid var(--card-border);
    margin-top: 26px;
    flex-wrap: wrap;
}

/* The photo button is a <label> wrapping a hidden InputFile, so it must read as a button. */
.profilehead label.row__button {
    cursor: pointer;
}

/* -------------------------------------------------- plan card (subscription)
   The one olive card in the app outside the sidebar; text and the ghost buttons inherit white. */
.plancard {
    background: var(--brand);
    border-radius: var(--radius-card);
    padding: 32px;
    color: #fff;
}

.plancard__eyebrow {
    font: 500 13px/1 var(--font);
    color: rgba(255, 255, 255, .7);
    text-transform: uppercase;
    letter-spacing: .1em;
}

.plancard__name {
    margin: 12px 0 6px;
    font: 500 32px/1.15 var(--font);
}

.plancard__meta {
    margin: 0 0 22px;
    font: 400 17px/1.5 var(--font);
    color: rgba(255, 255, 255, .85);
}

/* The line under the meta that says what the end of the product means (renewed as …, not renewed):
   pulled up against the meta, since the two read as one paragraph. */
.plancard__meta--renewal {
    margin-top: -14px;
}

.plancard__ghost {
    border: 1px solid rgba(255, 255, 255, .4);
    background: transparent;
    color: rgba(255, 255, 255, .85);
    padding: 15px 22px;
    border-radius: 13px;
    font: 500 16px/1 var(--font);
    cursor: pointer;
}

.plancard__ghost:hover:not(:disabled):not(.plancard__ghost--locked) {
    background: rgba(255, 255, 255, .12);
}

.plancard__ghost:disabled {
    opacity: .5;
    cursor: not-allowed;
}

/* Greyed like disabled, but still a button: the click opens the dialog that says how to stop. */
.plancard__ghost--locked {
    opacity: .5;
}

.paymentrow {
    grid-template-columns: 110px minmax(0, 1fr) minmax(0, .8fr) 150px 118px;
}

/* -------------------------------------------------- contracts to sign: one row per contract, in the alert card */
.contractrows {
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin-top: 12px;
}

.contractrow {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 10px 16px;
    padding: 12px 0 0;
    border-top: 1px solid rgba(0, 0, 0, .08);
}

.contractrow__main {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.contractrow__name {
    font: 500 17px/1.3 var(--font);
}

.contractrow__meta {
    font: 400 15px/1.3 var(--font);
    color: var(--muted);
}

/* The dashboard's block button as an anchor: same box, centred text, no underline. */
a.btn--block {
    display: block;
    text-align: center;
    text-decoration: none;
    box-sizing: border-box;
}

a.btn--block + a.btn--block {
    margin-top: 10px;
}

/* -------------------------------------------------- benefits page: referral rows and code chip */
/* The amount column of a referral row. The class keeps the name of the voucher row it was written
   for; that row went with the vouchers card. */
.voucherrow__amount {
    font: 500 19px/1.2 var(--font);
    text-align: right;
    /* Belt and braces with MoneyFormatting.Euro's non-breaking space: the sign and the number are
       one thing, and a 90px column must never split them. */
    white-space: nowrap;
}

/* The members a member brought in - name and date, amount, pill. Grid, not flex: the amount and the
   status pill each get a fixed column, so a wide pill on one row ("In behandeling") cannot push its
   neighbour's amount out of line. */
.referralrow {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 90px 130px;
    gap: 14px 20px;
    align-items: center;
    padding: 18px 0;
    border-bottom: 1px solid var(--hairline);
}

.referralrow:last-child {
    border-bottom: 0;
}

.referralrow .badge {
    justify-self: end;
}

@media (max-width: 640px) {
    .referralrow {
        grid-template-columns: minmax(0, 1fr);
    }

    .referralrow .badge {
        justify-self: start;
    }

    .voucherrow__amount {
        text-align: left;
    }
}

.vouchercode {
    flex: none;
    padding: 12px 16px;
    background: var(--surface-neutral);
    border: 2px dashed var(--olive);
    border-radius: 12px;
    font: 500 18px/1 var(--font);
    letter-spacing: .05em;
}

/* The referral card: explanation left, the member's own code as a large dashed chip right - the
   design's reading of "in het groot, rechts, met streepjesrand". One column on a phone. */
.referral {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 24px 40px;
    align-items: center;
}

.referral__how {
    margin: 12px 0 8px;
    font: 400 17px/1.5 var(--font);
}

.referral__amount {
    margin: 0 0 8px;
    font: 500 19px/1.4 var(--font);
}

.referral__codebox {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 14px;
}

/* Selectable in one click: the fallback when the clipboard is refused, and what the failure toast
   promises. */
.vouchercode--hero {
    padding: 22px 30px;
    font-size: 34px;
    letter-spacing: .14em;
    user-select: all;
}

@media (max-width: 640px) {
    .referral {
        grid-template-columns: minmax(0, 1fr);
    }

    .referral__codebox {
        align-items: flex-start;
    }
}

/* -------------------------------------------------- document rows */
.docbadge {
    width: 46px;
    height: 46px;
    flex: none;
    border-radius: 12px;
    background: var(--canvas);
    color: var(--deep);
    display: flex;
    align-items: center;
    justify-content: center;
    font: 500 13px/1 var(--font);
}

.docbadge--measurement {
    background: var(--surface-green);
    color: var(--green-text);
}

.docbadge--pending {
    background: var(--surface-orange);
    color: var(--rust);
}

/* -------------------------------------------------- responsive
   The artboards are desktop. Below 1024px the sidebar becomes a horizontal strip rather than
   disappearing behind a hamburger: eleven destinations is too many to hide, and the audience for
   this portal is not one that hunts for menus. */

@media (max-width: 1024px) {
    .shell {
        display: block;
        height: auto;
        min-height: 100vh;
        overflow: visible;
    }

    /* Off-canvas, slid in on demand. The previous horizontal strip pushed destinations off the right
       edge with nothing to indicate they were there - eight of them, on the screen size where a
       member is most likely to be looking for one. */
    .sidebar {
        position: fixed;
        top: 0;
        left: 0;
        bottom: 0;
        z-index: 60;
        width: min(var(--sidebar-width), 84vw);
        transform: translateX(-100%);
        transition: transform .22s ease;
        box-shadow: 0 0 40px rgba(28, 26, 18, .28);
    }

    .sidebar--open {
        transform: translateX(0);
    }

    .sidebar-backdrop {
        display: block;
        position: fixed;
        inset: 0;
        z-index: 50;
        background: rgba(28, 26, 18, .5);
        opacity: 0;
        pointer-events: none;
        transition: opacity .22s ease;
    }

    .sidebar-backdrop--visible {
        opacity: 1;
        pointer-events: auto;
    }

    .menutoggle {
        display: inline-flex;
    }

    .shell__main {
        overflow: visible;
    }

    .shell__body {
        padding: 24px 20px 48px;
    }

    .topbar {
        padding: 12px 20px;
        gap: 12px;
    }
}

/* Respect a reduced-motion preference: the drawer still opens, it just does not slide. */

@media (prefers-reduced-motion: reduce) {
    .sidebar,
    .sidebar-backdrop {
        transition: none;
    }
}

@media (max-height: 720px), (max-width: 560px) {
    .slotlist {
        height: 42vh;
    }
}

@media (max-width: 560px) {
    .topbar {
        flex-wrap: wrap;
        gap: 12px;
    }

    /* One line in the header: sign-out shrinks to its icon. (The language pill's own compaction
       lives with the pill, in the design system's stylesheet.) */
    .identity__signout {
        padding: 8px;
    }

    .identity__signout-label {
        display: none;
    }

    .identity__signout-icon {
        display: block;
    }
}

/* A flex column so a lone card inside (signedout, welcome) can centre itself vertically with
   margin:auto - a block parent gives margin:auto no height to distribute. */
.shell--bare {
    display: flex;
    flex-direction: column;
    height: auto;
    min-height: 100vh;
    overflow: visible;
    padding: 40px 20px;
}

/* -------------------------------------------------- welcome (the public landing page) */
.welcome {
    display: flex;
    flex-direction: column;
    gap: 18px;

    /* Fills the bare shell so the card centres vertically; the 80px is its 40px padding twice. */
    min-height: calc(100vh - 80px);
}

.welcome__lang {
    display: flex;
    justify-content: flex-end;
    max-width: 1100px;
    width: 100%;
    margin: 0 auto;
}

.welcome__divider {
    border: 0;
    border-top: 1px solid var(--hairline);
    margin: 4px 0;
}

.welcome__help {
    margin: 8px 0 0;
    font: 400 15px/1.5 var(--font);
    color: var(--muted);
}

.welcome__help a {
    color: var(--green-text);
    font-weight: 500;
    margin-left: 6px;
}

/* -------------------------------------------------- auth failure
   The identity provider's own message, shown verbatim. Preformatted because B2C's errors are
   multi-line and carry a correlation id support will ask for; wrapped rather than scrolled so the
   whole thing is selectable without a horizontal scrollbar. */
.authfailure {
    margin: 0;
    padding: 14px 16px;
    background: var(--surface-neutral);
    border: 1px solid var(--border);
    border-radius: var(--radius-control);
    font: 400 13px/1.5 ui-monospace, SFMono-Regular, Menlo, monospace;
    color: var(--ink);
    white-space: pre-wrap;
    word-break: break-word;
    max-height: 40vh;
    overflow-y: auto;
}

/* -------------------------------------------------- consent gate
   Covers the whole content area and cannot be dismissed: while a consent is outstanding there is
   nothing behind it a member is allowed to see. */
.consentgate {
    display: flex;
    justify-content: center;
    padding: 8px 0 40px;
}

.consentgate__panel {
    background: #fff;
    border: 1px solid var(--card-border);
    border-radius: var(--radius-card);
    padding: 32px 36px;
    max-width: 760px;
    width: 100%;
}

.consentgate__title {
    margin: 12px 0 18px;
    font: 500 26px/1.2 var(--font);
}

/* The element styling (paragraphs, headings) comes from .consentbody, shared with the consents
   page - the content is rendered Markdown on both. No pre-wrap: the renderer produces real
   paragraphs, and pre-wrap would add every source newline on top of them. */
.consentgate__body {
    font: 400 17px/1.6 var(--font);
    color: var(--ink);
    max-height: 46vh;
    overflow-y: auto;
    padding-right: 8px;
    margin-bottom: 24px;
}

.consentgate__error {
    margin: 0 0 16px;
    font: 500 16px/1.4 var(--font);
    color: var(--rust);
}

/* -------------------------------------------------- selectable session row
   A button so it is keyboard-operable, reset back to looking like the design's plain row. */
.sessionrow {
    width: 100%;
    border-left: 0;
    border-right: 0;
    border-bottom: 0;
    background: transparent;
    text-align: left;
    cursor: pointer;
    font: inherit;
    color: inherit;

    /* Padding so the selected row's background clears the status dot and the type pill instead of
       cutting flush against them; the matching negative margin lets that background bleed toward the
       card edge, so the row's text stays aligned with everything above it. */
    padding-left: 14px;
    padding-right: 14px;
    margin-left: -14px;
    margin-right: -14px;
    width: calc(100% + 28px);
    border-radius: 10px;
}

.sessionrow:hover {
    background: var(--surface-neutral);
}

.sessionrow--selected {
    background: var(--surface-neutral);
}

.sessionrow:focus-visible {
    outline: 2px solid var(--brand);
    outline-offset: -2px;
}

.rescheduledialog {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

/*
    The measure item charts dialog's frame.

    The admin portal has .dialog--tall for this; the MY portal never needed one, because every dialog
    here has been short enough to size to its content. A trend chart plus a row per measurement is
    not - so without a bounded, scrolling body the content ran off the bottom of the frame with
    nothing to scroll, and the close button sat directly under a short bar chart rather than at the
    foot of the dialog.

    BOTH OF RADZEN'S BOXES HAVE TO BE TOLD, and forgetting the inner one is what makes this look like
    it did nothing: the Height on the dialog reaches .rz-dialog, and .rz-dialog-content underneath it
    keeps sizing to its content regardless - so the frame is 80vh and everything inside it still
    stacks at its natural height, button included. The admin portal's .dialog--tall carries the same
    pair, and its comment records the same mistake.

    Scoped with :has() so it reaches only this dialog: every other dialog in this portal is content-
    sized on purpose, and a blanket rule would stretch a two-line confirmation to 80vh.
*/
.rz-dialog:has(.itemcharts) {
    display: flex;
    flex-direction: column;
}

.rz-dialog:has(.itemcharts) .rz-dialog-content {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
    /* The body scrolls, not this. Two nested scrollbars is the failure mode here. */
    overflow: hidden;
}

/*
    The BODY scrolls and the FOOT does not, which is what puts the button in the same place whichever
    chart is showing - under a tall trend and under a short bar alike.
*/
.itemcharts {
    display: flex;
    flex-direction: column;
    gap: 20px;
    flex: 1 1 auto;
    min-height: 0;
}

.itemcharts__body {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
}

.itemcharts__foot {
    flex: none;
    display: flex;
    justify-content: flex-end;
    gap: 10px;
    padding-top: 4px;
}
