/* psi-overflow: the parts any server-rendered page is built from.
 *
 * Design tokens come from shared/theme.css (generated from /shared/src/css/theme.css)
 * and are never redefined here; the fields and the buttons' base come from
 * shared/controls.css. Mobile first; dark mode follows the tokens.
 *
 * Each shell adds its own stylesheet after this one (public.css, auth.css,
 * admin.css, the admin's after menus.css), and a page that lists questions
 * adds questions.css.
 */

/* base */

html {
    -webkit-text-size-adjust: 100%;
    /* Reserve the scrollbar's space always, so navigating between a short page
       and a long one does not shift the layout sideways. */
    scrollbar-gutter: stable;
}

body {
    margin: 0;
    background: var(--psi-overflow-paper);
    color: var(--psi-overflow-ink);
    font-family: var(--psi-overflow-font);
    font-size: 1rem;
    line-height: 1.55;
    -webkit-font-smoothing: antialiased;
}

h1,
h2,
h3 {
    margin: 0;
    line-height: 1.2;
    letter-spacing: -0.02em;
    font-weight: 700;
}

h1 {
    font-size: 1.55rem;
}

h2 {
    font-size: 1.1rem;
}

h3 {
    font-size: 0.95rem;
}

p {
    margin: 0 0 0.75rem;
    max-width: var(--psi-overflow-measure, 64ch);
}

p:last-child {
    margin-bottom: 0;
}

a {
    color: var(--psi-overflow-accent);
    text-decoration-thickness: 1px;
    text-underline-offset: 2px;
}

a:hover {
    color: var(--psi-overflow-accent-hover);
}

:focus-visible {
    outline: 2px solid var(--psi-overflow-accent);
    outline-offset: 2px;
}

svg.icon {
    display: block;
    flex: none;
}

.skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 50;
    background: var(--psi-overflow-surface);
    padding: 0.6rem 1rem;
    border-radius: 0 0 var(--psi-overflow-radius) 0;
    box-shadow: var(--psi-overflow-shadow-pop);
}

.skip-link:focus {
    left: 0;
}

/* layout */

.page {
    --gutter: 1rem;
    max-width: 68rem;
    margin: 0 auto;
    padding: 0 var(--gutter) 4rem;
}

.masthead {
    padding: 1rem 0 0.85rem;
    border-bottom: 1px solid var(--psi-overflow-rule);
}

/* It wraps, so each item keeps its space above and to the left as a margin,
   and the bar takes the first line's back: the items wrap where they would
   with flex `gap`, which Safari 13 does not know. The bar is an element of
   its own, so the rule under the masthead stays where it is. */
.masthead__bar {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    margin: -0.5rem 0 0 -0.75rem;
}

.masthead__bar > * {
    margin-top: 0.5rem;
    margin-left: 0.75rem;
}

.masthead__title {
    font-weight: 700;
    font-size: 1rem;
    letter-spacing: -0.01em;
    color: inherit;
    text-decoration: none;
}

.masthead__spacer {
    flex: 1 1 auto;
}

/* The public pages' language switch (below): drawn as a quiet control, not
   as a field or body text, so it is obviously clickable. */
.language-switch__control select {
    display: inline-flex;
    align-items: center;
    padding: 0.25rem 0.55rem;
    border-radius: var(--psi-overflow-radius);
    border: 1px solid transparent;
    color: var(--psi-overflow-ink-soft);
    font-size: 0.9rem;
    font-weight: 550;
}

.language-switch__control select:hover {
    background: var(--psi-overflow-surface-sunk);
    border-color: var(--psi-overflow-rule);
    color: var(--psi-overflow-ink);
}

.lede {
    color: var(--psi-overflow-ink-soft);
    margin-bottom: 1.5rem;
    max-width: var(--psi-overflow-measure, 64ch);
}

.section {
    margin-bottom: 2.25rem;
}

.section:last-child {
    margin-bottom: 0;
}

.section__head {
    display: flex;
    align-items: baseline;
    margin-bottom: 0.85rem;
}

.section__head > * + * {
    margin-left: 0.75rem;
}

.section__head h2 {
    flex: none;
}

.section__rule {
    flex: 1 1 auto;
    height: 1px;
    background: var(--psi-overflow-rule);
}

.section__count {
    flex: none;
    color: var(--psi-overflow-ink-faint);
    font-size: 0.85rem;
    font-variant-numeric: tabular-nums;
}

/* A page's title and its lede. */
.page-head {
    margin: 1.25rem 0;
}

.page-head .lede {
    margin-bottom: 0;
}

/* The languages a public page can be read in (§9), at the masthead's end:
   a native select that does not look like one. Its own look is taken off,
   and it is drawn as a quiet control (above): the languages icon, the
   language, and a quiet ground on hover.
   The icon lies over the select's padding and lets clicks through, so the
   whole control opens it. Its button is only ever seen without script
   (`<noscript>`). Margins rather than flex `gap`, which Safari 13 does not
   know. */
.language-switch {
    display: flex;
    align-items: center;

    & > * + * {
        margin-left: 0.5rem;
    }
}

.language-switch__control {
    position: relative;
    display: inline-flex;
    align-items: center;
    color: var(--psi-overflow-ink-soft);

    svg {
        position: absolute;
        left: 0.55rem;
        pointer-events: none;
    }

    /* Room on the left for the icon; as wide as the language shown, not the
       longest one listed, where the browser can size a select to its
       content, and elsewhere as wide as the longest. */
    select {
        field-sizing: content;
        width: auto;
        min-height: 0;
        padding-left: 1.9rem;
        background: none;
        cursor: pointer;
    }

    &:hover {
        color: var(--psi-overflow-ink);
    }

    select:focus {
        border-color: var(--psi-overflow-accent);
    }
}

/* A list with nothing in it yet, said in words. */
.empty {
    margin: 0;
    padding: 0.35rem 0;
    color: var(--psi-overflow-ink-soft);
}

/* pills: a state, or what a row is */

/* Inline-block, so its words are its baseline and a pill in running text
   sits on the line of the words beside it. */
.pill {
    display: inline-block;
    padding: 0.05rem 0.5rem 0.1rem;
    border-radius: 999px;
    font-size: 0.8125rem;
    line-height: 1.45;
    white-space: nowrap;
    background: var(--psi-overflow-surface-sunk);
    color: var(--psi-overflow-ink-soft);
    border: 1px solid var(--psi-overflow-rule);
}

.pill--review {
    background: var(--psi-overflow-review-wash);
    color: var(--psi-overflow-review);
    border-color: transparent;
}

.pill--public {
    background: var(--psi-overflow-accent-wash);
    color: var(--psi-overflow-accent);
    border-color: transparent;
}

.pill--closed {
    background: var(--psi-overflow-danger-wash);
    color: var(--psi-overflow-danger);
    border-color: transparent;
}

/* surfaces */

.panel {
    position: relative;
    background: var(--psi-overflow-surface);
    border: 1px solid var(--psi-overflow-rule);
    border-radius: var(--psi-overflow-radius-large);
    padding: 1.15rem;
    margin-bottom: 1.15rem;
}

.panel:last-child {
    margin-bottom: 0;
}

.panel__title,
.chart-title {
    margin-bottom: 0.85rem;
}

.panel__title + .panel__hint,
.chart-title + .panel__hint {
    margin-top: -0.65rem;
}

.panel__hint {
    color: var(--psi-overflow-ink-soft);
    font-size: 0.9rem;
    margin-bottom: 1rem;
    max-width: 62ch;
}

.panel--danger {
    border-color: var(--psi-overflow-danger);
}

.notice {
    display: flex;
    align-items: flex-start;
    padding: 0.7rem 0.85rem;
    border-radius: var(--psi-overflow-radius);
    background: var(--psi-overflow-surface-sunk);
    border: 1px solid var(--psi-overflow-rule);
    color: var(--psi-overflow-ink-soft);
    font-size: 0.9375rem;
    line-height: 1.5;
    margin-bottom: 1.15rem;
}

.notice > * + * {
    margin-left: 0.6rem;
}

/* One line high, so the icon in it is centred on the first line of the
   words, whatever its size. */
.notice__icon {
    display: flex;
    flex: none;
    align-items: center;
    height: 1.5em;
}

.notice--warn {
    background: var(--psi-overflow-review-wash);
    border-color: transparent;
    color: var(--psi-overflow-ink);
}

.notice--error {
    background: var(--psi-overflow-danger-wash);
    border-color: transparent;
    color: var(--psi-overflow-ink);
}

.notice--ok {
    background: var(--psi-overflow-answered-wash);
    border-color: transparent;
    color: var(--psi-overflow-ink);
}

.notice--info {
    background: var(--psi-overflow-accent-wash);
    border-color: transparent;
}

/* What can be done about it, beside the words and centred on them. */
.notice__action {
    flex: none;
    align-self: center;
    margin-left: auto;
    min-height: 40px;
    background: var(--psi-overflow-surface);
}

/* The answer to a form, pinned to the bottom of the viewport so it is seen
   wherever on the page the form was (toast.html). The wash is opaque here and
   lifted off the page, since it floats over whatever is underneath. */
.notice--floating {
    position: fixed;
    z-index: 100;
    left: 50%;
    bottom: calc(1.25rem + env(safe-area-inset-bottom, 0px));
    width: max-content;
    max-width: min(34rem, calc(100% - 2rem));
    margin: 0;
    align-items: center;
    padding: 0.6rem 0.5rem 0.6rem 0.85rem;
    border-color: var(--psi-overflow-rule);
    box-shadow: var(--psi-overflow-shadow-pop);
    transform: translateX(-50%);
    animation: toast-in 0.2s cubic-bezier(0.22, 1, 0.36, 1);
}

.notice--floating svg {
    flex: none;
    margin-top: 0;
}

.notice--floating.is-leaving {
    opacity: 0;
    transform: translate(-50%, 0.5rem);
    transition:
        opacity 0.2s ease,
        transform 0.2s ease;
}

.notice__text {
    flex: 1 1 auto;
    min-width: 0;
}

/* A line of its own over the words, in the page's ink. */
.notice__title {
    display: block;
    color: var(--psi-overflow-ink);
}

/* A field among the words, such as a value to copy, on its own line. */
.notice__field {
    margin: 0.45rem 0 0.55rem;
}

.notice__close {
    flex: none;
    display: grid;
    place-items: center;
    width: 2rem;
    height: 2rem;
    /* Left, the notice's space before it. */
    margin: -0.3rem 0 -0.3rem 0.6rem;
    padding: 0;
    border: 0;
    border-radius: var(--psi-overflow-radius-small);
    background: transparent;
    color: var(--psi-overflow-ink-soft);
    font: inherit;
    font-size: 1.25rem;
    line-height: 1;
    cursor: pointer;
}

.notice__close:hover {
    background: rgba(0, 0, 0, 0.06);
    color: var(--psi-overflow-ink);
}

.notice__close:focus-visible {
    outline: 2px solid var(--psi-overflow-accent);
    outline-offset: -2px;
}

@keyframes toast-in {
    from {
        opacity: 0;
        transform: translate(-50%, 0.75rem);
    }
    to {
        opacity: 1;
        transform: translate(-50%, 0);
    }
}

/* buttons (base and --primary come from controls.css) */

.button--danger:not(:disabled) {
    border-color: transparent;
    background: transparent;
    color: var(--psi-overflow-danger);
}

.button--danger:hover:not(:disabled) {
    background: var(--psi-overflow-danger-wash);
    border-color: var(--psi-overflow-danger);
    color: var(--psi-overflow-danger);
}

.button--quiet {
    padding-inline: 0.5rem;
}

.button--quiet:not(:disabled) {
    border-color: transparent;
    background: transparent;
    color: var(--psi-overflow-ink-soft);
}

.button--quiet:hover:not(:disabled) {
    background: var(--psi-overflow-surface-sunk);
    border-color: var(--psi-overflow-rule);
}

/* A quiet button that is also the current page. */
.button--quiet[aria-current='page']:not(:disabled) {
    background: var(--psi-overflow-accent-wash);
    border-color: transparent;
    color: var(--psi-overflow-accent);
}

/* A button that is only an icon, as the embed draws its own
   (embed/src/ui/base.css): no border, the icon soft until hovered, the focus
   ring inside its box. Each use sets its size and place. */
.icon-button {
    flex: none;
    display: grid;
    place-items: center;
    padding: 0;
    border: 0;
    border-radius: var(--psi-overflow-radius);
    background: transparent;
    color: var(--psi-overflow-ink-soft);
    cursor: pointer;
}

.icon-button:hover {
    background: var(--psi-overflow-surface-sunk);
    color: var(--psi-overflow-ink);
}

.icon-button:focus-visible {
    outline: 2px solid var(--psi-overflow-accent);
    outline-offset: -2px;
}

.button--small {
    min-height: 2rem;
    font-size: 0.875rem;
    padding: 0.25rem 0.6rem;
}

/* A button as wide as it is high, for an icon alone. */
.button--square {
    padding-left: 0;
    padding-right: 0;
    min-width: 2rem;
}

/* Buttons joined into one control, for one choice between them. The edge two
   share is drawn once, the second over the first by its border's width; the
   one under the pointer or the focus comes to the top, all of its border
   with it. */
.button-group {
    display: inline-flex;
}

.button-group > .button {
    position: relative;
    border-radius: 0;
}

.button-group > .button + .button {
    margin-left: -1px;
}

.button-group > .button:first-child {
    border-top-left-radius: var(--psi-overflow-radius);
    border-bottom-left-radius: var(--psi-overflow-radius);
}

.button-group > .button:last-child {
    border-top-right-radius: var(--psi-overflow-radius);
    border-bottom-right-radius: var(--psi-overflow-radius);
}

.button-group > .button:hover,
.button-group > .button:focus-visible {
    z-index: 1;
}

/* It wraps, so each item keeps its space below and to the left as a margin,
   and the row takes the last line's and its left edge back: the items wrap
   where they would with flex `gap`, which Safari 13 does not know. Below
   rather than above, so its own top margin collapses as it always did. */
.button-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    margin-bottom: -0.5rem;
    margin-left: -0.5rem;
}

/* A fieldset is `display: contents` (controls.css): its children are the
   row's items. */
.button-row > *,
.button-row > fieldset > * {
    margin-bottom: 0.5rem;
    margin-left: 0.5rem;
}

/* form controls */

.field {
    display: block;
    margin-bottom: 1rem;
}

.field:last-child {
    margin-bottom: 0;
}

.field__label {
    display: block;
    font-size: 0.9rem;
    font-weight: 550;
    margin-bottom: 0.3rem;
}

.field__hint {
    display: block;
    color: var(--psi-overflow-ink-faint);
    font-size: 0.8125rem;
    margin-top: 0.3rem;
}

/* It wraps, so each item keeps its space above and to the left as a
   margin, and the form takes the first line's back: the items wrap where
   they would with flex `gap`, which Safari 13 does not know. */
.inline-form {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    margin: -0.6rem 0 0 -0.6rem;
}

/* A fieldset is `display: contents` (controls.css): its children are the
   form's items. */
.inline-form > *,
.inline-form > fieldset > * {
    margin-top: 0.6rem;
    margin-left: 0.6rem;
}

.inline-form .field {
    margin-bottom: 0;
    flex: 1 1 10rem;
    min-width: 0;
}

/* On a phone each field of an inline form takes a row of its own, and so
   does its button, as does the save of a form that is not one
   (`.button--full-on-phone`): two selects side by side would cut their
   choices off, and a button under its fields is a target for the thumb. A
   row's own icon buttons, such as a website's bin, keep their size. */
@media (max-width: 34rem) {
    .inline-form .field {
        flex-basis: 100%;
    }

    .inline-form > .button,
    .inline-form > fieldset > .button,
    .button--full-on-phone {
        width: 100%;
    }
}

.check {
    display: flex;
    align-items: flex-start;
    padding: 0.35rem 0;
    cursor: pointer;
}

.check > * + * {
    margin-left: 0.55rem;
}

.check input {
    width: auto;
    min-height: 0;
    margin-top: 0.3rem;
    accent-color: var(--psi-overflow-accent);
}

.check__body {
    font-size: 0.9375rem;
}

/* htmx feedback: a button that sent a request, or the buttons of a form that
   did (htmx marks the form, not its submit button), wait for the answer. */

.htmx-request.button,
form.htmx-request .button {
    opacity: 0.6;
    pointer-events: none;
}

/* wider screens */

@media (min-width: 40rem) {
    .page {
        --gutter: 1.5rem;
        padding-bottom: 5rem;
    }

    h1 {
        font-size: 1.8rem;
    }
}

@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.001ms !important;
        scroll-behavior: auto !important;
    }
}
