/*
 * Quisim theme for SimpleSAMLphp.
 *
 * Loaded from _head.twig, i.e. AFTER SimpleSAMLphp's own stylesheet.css. That
 * file stays in place — it carries pure.css's grid and form layout plus the
 * Font Awesome icons, and reimplementing it would be a maintenance burden for
 * no gain. What we do here is retheme it: the stock look is a red gradient
 * header/footer, this makes it the Quisim palette from the marketing site
 * (--vp-c-brand-* in quisimcom/.vitepress/theme/style.css) so the login form a
 * user lands on doesn't look like a different product.
 *
 * Everything is driven by the custom properties below. Dark mode follows the
 * OS setting; SimpleSAMLphp has no theme toggle of its own.
 */

:root {
    --q-brand: #4a7;
    --q-brand-dark: #3a6455;
    --q-brand-hover: #576;

    --q-bg: #ffffff;
    --q-bg-soft: #f6f6f7;
    --q-bg-card: #ffffff;
    --q-text: #3c3c43;
    --q-text-2: #67676c;
    --q-border: #e2e2e3;
    --q-shadow: 0 1px 2px rgba(0, 0, 0, 0.04), 0 6px 24px rgba(0, 0, 0, 0.06);
}

@media (prefers-color-scheme: dark) {
    :root {
        --q-brand: #4a7;
        --q-brand-dark: #6b7;
        --q-brand-hover: #6b7;

        --q-bg: #1b1b1f;
        --q-bg-soft: #202127;
        --q-bg-card: #202127;
        --q-text: #dfdfd6;
        --q-text-2: #98989f;
        --q-border: #2e2e32;
        --q-shadow: 0 1px 2px rgba(0, 0, 0, 0.2), 0 6px 24px rgba(0, 0, 0, 0.3);
    }
}

/* ---------------------------------------------------------------- page shell */

body {
    font-family:
        system-ui,
        -apple-system,
        "Segoe UI",
        sans-serif;
    background: var(--q-bg);
    color: var(--q-text);
}

#content {
    padding-top: 3rem;
}

/* The stock theme wraps content at 80%/1100px, which leaves a login form
   stranded in a very wide column. Auth pages are narrow by nature. */
#content .wrap {
    box-sizing: border-box;
    width: 100%;
    max-width: 688px;
    padding: 0 24px;
    margin: 0 auto;
}

/* core/base.twig puts the content in #portalmenu — turn it into a card. */
#portalmenu,
#portalcontent {
    background: var(--q-bg-card);
    border: none;
}

#portalmenu {
    border: 1px solid var(--q-border);
    border-radius: 14px;
    box-shadow: var(--q-shadow);
    overflow: hidden;
}

#portalcontent {
    padding: 2rem 2.25rem 2.5rem;
}

@media screen and (max-width: 40em) {
    #portalcontent {
        padding: 1.5rem 1.25rem 2rem;
    }
    #content {
        padding-top: 1.5rem;
    }
}

/* ------------------------------------------------------------------- header */

/*
 * Matched to the marketing site's nav bar, which is VitePress's VPNavBar: 64px
 * tall, a 24px logo mark, and a 16px/600 wordmark set in Bitstream Vera Sans
 * (quisimcom/.vitepress/theme/style.css sets .VPNavBarTitle .title to it while
 * leaving the body font as system-ui). The font files are copied in rather than
 * loaded from www.quisim.com so the login page carries no cross-origin request
 * — an auth page that depends on another host to render is a page that breaks
 * in exactly the situations you least want it to.
 */
@font-face {
    font-family: "Bitstream Vera Sans";
    src:
        local("Bitstream Vera Sans"),
        url("Vera.woff2") format("woff2"),
        url("Vera.woff") format("woff");
    font-display: swap;
}

@font-face {
    font-family: "Bitstream Vera Sans";
    src:
        local("Bitstream Vera Sans"),
        url("VeraBd.woff2") format("woff2"),
        url("VeraBd.woff") format("woff");
    font-weight: bold;
    font-display: swap;
}

#header {
    height: 4rem;
    background: var(--q-bg);
    border-bottom: 1px solid var(--q-border);
}

/*
 * VitePress's nav is an outer full-width .wrapper with `padding: 0 32px` (24px
 * below 768px) around a .container of `max-width: calc(--vp-layout-max-width -
 * 64px)` = 1376px with `margin: 0 auto`. The padding therefore never adds to
 * the centring: content starts at (viewport - 1376) / 2 once the viewport is
 * wide enough, and the padding only takes over below that.
 *
 * Collapsed into the single .wrap element SSP gives us by setting max-width to
 * the FULL layout width (1440 = 1376 + 2 * 32) and letting border-box eat the
 * padding — the inner box is then min(viewport - 64, 1376), which is what
 * VitePress computes. Setting max-width to 1376 here instead would indent
 * everything by an extra 32px, which is the bug this replaces.
 *
 * box-sizing is explicit: SSP's reset is `* { margin: 0; padding: 0 }` only, it
 * never sets border-box, so without this the padding would be added to the max.
 */
#header .wrap,
#footer .wrap {
    box-sizing: border-box;
    width: 100%;
    max-width: 1440px;
    padding: 0 32px;
}

@media screen and (max-width: 48em) {
    #header .wrap,
    #footer .wrap {
        padding: 0 24px;
    }
}

#header .logo-header,
#header .language-bar {
    height: 4rem;
}

#logo {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 1rem;
    font-weight: 600;
    letter-spacing: normal;
    color: var(--q-text);
    text-decoration: none;
    text-shadow: none;
}

#logo:hover,
#logo:focus {
    background: none;
    color: var(--q-text);
    padding: 0;
}

/* Kept in sync with the width/height attributes on the <img> in _header.twig,
   which are there so the bar does not reflow before the CSS lands. */
#logo img {
    display: block;
    width: 24px;
    height: 24px;
}

.logo-text {
    white-space: nowrap;
    font-family: "Bitstream Vera Sans", system-ui, sans-serif;
}

@media screen and (max-width: 40em) {
    #header,
    #header .logo-header,
    #header .language-bar {
        height: 3.5rem;
    }
    .logo-text {
        /* the theme.header string is long — the mark alone carries it here */
        display: none;
    }

    /* Below 40em the stock sheet hides the language <select> and shows this
       globe pull-out link instead. Its stock box is `height: 2rem` plus
       `padding: 2rem 0` — 6rem, sized for SSP's original 6rem header, so
       against our 3.5rem bar it overflowed and dragged the layout with it.
       Centre it in the bar at nav-icon size instead. */
    .menu-link,
    .menu-link:hover,
    .menu-link:focus {
        display: flex;
        align-items: center;
        height: 3.5rem;
        padding: 0;
    }

    .menu-link span.fa-2x {
        font-size: 1.35rem;
        padding: 0;
    }
}

/* Language pull-out menu (small screens) — stock colour is SSP red. */
#menu {
    background: var(--q-brand-dark);
}

#menu .pure-menu-selected,
#menu .pure-menu-heading {
    background: var(--q-brand);
}

#menu .pure-menu ul,
#menu .pure-menu .menu-item-divided {
    border-top: 1px solid rgba(255, 255, 255, 0.2);
}

.menu-link span {
    color: var(--q-text);
}

/* The marketing nav has no equivalent control, so this is styled to sit at the
   weight of its nav links (14px/500, quiet colour) rather than as a form field:
   the border only appears on hover/focus. It is still a <select>, so the native
   disclosure arrow keeps it recognisably clickable. */
.language-menu {
    border-radius: 6px;
    border: 1px solid transparent;
    background: none;
    color: var(--q-text-2);
    font-size: 0.875rem;
    font-weight: 500;
    /* Stock SSP sets min-width: 10rem. Kept, because the widest language name in
       language.available is a good deal longer than "Deutsch" and a select that
       resizes per language makes the whole bar twitch. */
    min-width: 10rem;
    padding: 0.3em 0.5em !important;
}

.language-menu:hover {
    color: var(--q-text);
    border-color: var(--q-border);
}

.language-menu:focus {
    color: var(--q-text);
    border-color: var(--q-brand);
}

/* ------------------------------------------------------------------- footer */

#footer {
    background: var(--q-bg);
    border-top: 1px solid var(--q-border);
    color: var(--q-text-2);
    height: 4rem;
    padding: 1.75rem 0 0;
}

#footer a,
#footer a:visited {
    color: var(--q-text-2);
    text-decoration: none;
}

#footer a:hover,
#footer a:focus,
#footer a:visited:hover,
#footer a:visited:focus {
    background: none;
    color: var(--q-brand);
    padding: 0;
    margin: 0;
}

#footer .copyrights span {
    padding: 0 0.4rem;
    opacity: 0.5;
}

/* ------------------------------------------------------------------ content */

h1 {
    font-size: 1.6rem;
    font-weight: 700;
    letter-spacing: -0.02em;
    margin: 0 0 0.5rem;
    color: var(--q-text);
}

h2 {
    font-size: 1.25rem;
    font-weight: 600;
    color: var(--q-text);
    border-bottom: none;
    margin: 0 0 0.5rem;
}

h3 {
    color: var(--q-text);
}

p {
    color: var(--q-text-2);
}

/* The stock rule paints link hovers with a dark background and re-pads them,
   which makes text jump. Plain brand colour instead. */
a {
    color: var(--q-brand-dark);
}

a:hover,
a:focus {
    color: var(--q-brand);
    background: none;
    padding: 0;
    text-decoration: underline;
}

/* -------------------------------------------------------------------- forms */

.center-form {
    display: block;
}

.pure-form-aligned .pure-control-group label {
    color: var(--q-text-2);
    font-size: 0.9rem;
    width: 9em;
}

.pure-form input[type="text"],
.pure-form input[type="password"],
.pure-form input[type="email"],
.pure-form select,
.pure-form input.edge {
    border-radius: 8px;
    border: 1px solid var(--q-border);
    background: var(--q-bg);
    color: var(--q-text);
    padding: 0.55em 0.7em;
    box-shadow: none;
    font-size: 0.95rem;
}

.pure-form input[type="text"]:focus,
.pure-form input[type="password"]:focus,
.pure-form input[type="email"]:focus,
.pure-form select:focus {
    border-color: var(--q-brand);
    outline: 2px solid rgba(68, 170, 119, 0.25);
    outline-offset: 0;
}

.pure-control-group {
    margin-bottom: 1rem;
}

/* ------------------------------------------------------------------ buttons */

.pure-button {
    border-radius: 20px;
    margin-left: 0;
    padding: 0.5em 1.4em;
    font-weight: 600;
    font-size: 0.95rem;
    background: var(--q-bg-soft);
    color: var(--q-text);
    border: 1px solid var(--q-border);
    text-shadow: none;
}

.pure-button:hover,
.pure-button:focus {
    background: var(--q-bg-soft);
    border-color: var(--q-brand);
    color: var(--q-text);
    padding: 0.5em 1.4em;
}

/* The submit button on the login form and the "preferred source" button. */
.pure-button-primary,
.pure-button-selected,
.pure-button-active,
input[type="submit"].pure-button,
button[type="submit"].pure-button {
    background: var(--q-brand);
    border-color: var(--q-brand);
    color: #fff;
}

.pure-button-primary:hover,
.pure-button-primary:focus,
.pure-button-active:hover,
.pure-button-active:focus,
input[type="submit"].pure-button:hover,
input[type="submit"].pure-button:focus,
button[type="submit"].pure-button:hover,
button[type="submit"].pure-button:focus {
    background: var(--q-brand-hover);
    border-color: var(--q-brand-hover);
    color: #fff;
}

.pure-button-red {
    background: var(--q-brand);
    border-color: var(--q-brand);
}

.pure-button-red:hover,
.pure-button-red:focus {
    background: var(--q-brand-hover);
    border-color: var(--q-brand-hover);
}

/* ------------------------------------------------------------- message boxes */

.message-box {
    border-radius: 10px;
    border-left-width: 4px;
    background: var(--q-bg-soft);
    color: var(--q-text);
    box-shadow: none;
    border-left-style: solid;
    border-left-color: var(--q-border);
}

.message-box.error {
    background: rgba(204, 75, 55, 0.1);
    border-left-color: #cc4b37;
}

.message-box.warning {
    background: rgba(234, 179, 8, 0.12);
    border-left-color: #eab308;
}

.message-box.success {
    background: rgba(68, 170, 119, 0.12);
    border-left-color: var(--q-brand);
}

/* ------------------------------------------- multiauth source picker (OIDC) */

/*
 * Only reached by flows that don't come through /login.html — chiefly the OIDC
 * authorize endpoint used by quisim.desktop. Same card look as the web chooser.
 */
ul.authsources {
    list-style: none;
    padding: 0;
    margin: 1.5rem 0 0;
}

li.authsource {
    margin: 0 0 0.75rem;
}

li.authsource .pure-button {
    display: block;
    width: 100%;
    text-align: left;
    border-radius: 12px;
    padding: 1rem 1.1rem;
    background: var(--q-bg-soft);
    color: var(--q-text);
    border: 1px solid var(--q-border);
}

li.authsource .pure-button:hover,
li.authsource .pure-button:focus {
    border-color: var(--q-brand);
    background: var(--q-bg-soft);
    padding: 1rem 1.1rem;
}

li.authsource .pure-button-active {
    border-color: var(--q-brand);
    background: var(--q-bg-soft);
    color: var(--q-text);
}

li.authsource p {
    margin: 0.4rem 0 0;
    font-size: 0.85rem;
    color: var(--q-text-2);
}

/* ------------------------------------------------------------------- tables */

table.attributes th,
.pure-table-attributes th {
    color: var(--q-text-2);
}

/* ------------------------------------------------------- auth pages (login) */

/*
 * Mirrors the reset page's panel — quisimcom's
 * .vitepress/theme/components/ResetPanel.vue, live at /Auth/reset.html — so the
 * two steps of the same flow are visibly one design. Every number below is that
 * component's, with VitePress's custom properties mapped onto ours:
 *
 *     --vp-c-bg-soft -> --q-bg-soft     --vp-c-text-2  -> --q-text-2
 *     --vp-c-divider -> --q-border      --vp-c-brand-1 -> --q-brand
 *     --vp-c-bg      -> --q-bg          --vp-c-brand-2 -> --q-brand-hover
 *
 * The markup this styles is in themes/quisim/core/loginuserpass.twig, which
 * skips #portalmenu entirely — the reset page has no outer card, just this
 * panel on the page background.
 *
 * Several rules undo SSP's global element styles rather than being design
 * decisions of their own: `* { margin: 0; padding: 0 }` is the whole reset that
 * stylesheet.css ships, so h1/p/ul keep browser-ish margins, and its
 * `a:hover { background: #444; color: #fff; padding: .5em 1em }` would make
 * every link here jump and go dark on hover.
 */

/* #content carries padding of its own (2em top / 2rem bottom stock, raised to
   3rem here for the card pages). The auth column brings ResetPanel's own
   64/96px instead, so the wrapper's padding is taken back out — otherwise the
   two stack and the form sits far lower than it does on /Auth/reset.html. */
#content:has(.q-auth) {
    padding-top: 0;
    padding-bottom: 0;
}

.q-auth {
    box-sizing: border-box;
    width: 100%;
    max-width: 460px;
    margin: 0 auto;
    padding: 64px 0 96px;
    text-align: center;
}

.q-logo {
    display: block;
    width: 48px;
    height: 48px;
    margin: 0 auto 20px;
}

.q-title {
    margin: 0 0 8px;
    font-size: 28px;
    font-weight: 700;
    line-height: 1.2;
    letter-spacing: -0.02em;
    color: var(--q-text);
}

.q-sub {
    margin: 0 0 28px;
    padding: 0;
    font-size: 14px;
    color: var(--q-text-2);
}

/* ---- panel */

.q-form {
    margin-bottom: 12px;
    padding: 18px;
    text-align: left;
    border: 1px solid var(--q-border);
    border-radius: 12px;
    background: var(--q-bg-soft);
}

.q-field {
    margin-bottom: 16px;
}

.q-label {
    display: block;
    margin-bottom: 6px;
    font-size: 13px;
    font-weight: 600;
    color: var(--q-text);
}

.q-input {
    box-sizing: border-box;
    width: 100%;
    padding: 9px 12px;
    font-size: 14px;
    font-family: inherit;
    color: var(--q-text);
    background: var(--q-bg);
    border: 1px solid var(--q-border);
    border-radius: 8px;
    transition: border-color 0.2s;
}

.q-input:focus {
    outline: none;
    border-color: var(--q-brand);
}

.q-input:disabled {
    opacity: 0.6;
}

/* ResetPanel has no checkboxes; sized off .rs-hint, which is the small print
   that sits in the same position under a field. */
.q-check {
    display: flex;
    align-items: center;
    gap: 0.5em;
    margin: 8px 0 0;
    font-size: 12px;
    color: var(--q-text-2);
    cursor: pointer;
}

.q-check input[type="checkbox"] {
    margin: 0;
    accent-color: var(--q-brand);
}

.q-submit {
    display: block;
    width: 100%;
    padding: 11px 18px;
    font-size: 15px;
    font-weight: 600;
    font-family: inherit;
    color: #fff;
    background: var(--q-brand);
    border: 1px solid var(--q-brand);
    border-radius: 12px;
    cursor: pointer;
    transition:
        background-color 0.2s,
        opacity 0.2s,
        transform 0.1s;
}

.q-submit:hover:not(:disabled),
.q-submit:focus:not(:disabled) {
    background: var(--q-brand-hover);
    border-color: var(--q-brand-hover);
    color: #fff;
}

.q-submit:active:not(:disabled) {
    transform: translateY(1px);
}

.q-submit:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* ---- messages, matching .rs-info / .rs-error */

.q-alert {
    margin-bottom: 20px;
    padding: 14px 18px;
    text-align: left;
    font-size: 14px;
    border: 1px solid var(--q-border);
    border-radius: 12px;
    background: var(--q-bg-soft);
    color: var(--q-text-2);
}

.q-alert p {
    margin: 0;
    padding: 0;
}

.q-alert-title {
    font-weight: 600;
    color: var(--q-text);
}

.q-alert-title + .q-alert-detail {
    margin-top: 6px;
}

.q-alert-error {
    border-color: #cc4b37;
}

.q-alert-warning {
    border-color: #d9a441;
}

/* ---- the note under the panel */

.q-note {
    margin: 28px 0 0;
    padding: 0;
    font-size: 13px;
    color: var(--q-text-2);
}

/* One <p> per configured link — with two of them ("forgot my password" and the
   way back to the general sign-in page) a single joined line wraps badly in
   German. */
.q-note p {
    margin: 0;
    padding: 0;
}

.q-note p + p {
    margin-top: 8px;
}

.q-note a,
.q-alert a,
.q-sub a {
    color: var(--q-brand);
    text-decoration: none;
}

.q-note a:hover,
.q-note a:focus,
.q-alert a:hover,
.q-alert a:focus,
.q-sub a:hover,
.q-sub a:focus {
    background: none;
    padding: 0;
    color: var(--q-brand);
    text-decoration: underline;
}

@media screen and (max-width: 40em) {
    .q-auth {
        padding: 40px 0 64px;
    }

    .q-title {
        font-size: 24px;
    }
}
