/* files.rhys.wtf, in rhys.wtf's design language. The fonts, palette,
   tokens, dark scheme, header, toggle, apps mark and menu, section
   headings, footer and form controls are copied from diagrams'
   server/static/main.css (itself from profiles' and rhyswtf-rs's): keep
   them in step. The lists are Diagrams' too, renamed for files; Files'
   own parts are at the end. Recoleta is licensed for rhys.wtf sites only. */

@font-face {
    font-family: Recoleta;
    src: url('/static/Recoleta.woff2') format('woff2');
    font-display: swap;
}

@font-face {
    font-family: RecoletaBold;
    src: url('/static/RecoletaBold.woff2') format('woff2');
    font-display: swap;
}

@font-face {
    font-family: Figtree;
    src: url('/static/Figtree-Regular.woff2') format('woff2');
    font-display: swap;
}

@font-face {
    font-family: Lora-Italic;
    src: url('/static/Lora-Italic-VariableFont_wght.woff2') format('woff2');
    font-display: swap;
}

:root {
    /* The rhys.wtf type system: Recoleta Bold for headings, Recoleta for
       reading, Figtree for the interface, Lora Italic for the logo only. */
    --font-body: Recoleta, system-ui, -apple-system, sans-serif;
    --font-display: RecoletaBold, Recoleta, system-ui, sans-serif;
    --font-ui: Figtree, system-ui, -apple-system, sans-serif;
    --font-italic: Lora-Italic, Georgia, serif;

    /* Gruvbox light palette — https://github.com/morhetz/gruvbox */
    --gruvbox-bg0-hard: #f9f5d7;
    --gruvbox-bg0: #fbf1c7;
    --gruvbox-bg0-soft: #f2e5bc;
    --gruvbox-bg1: #ebdbb2;
    --gruvbox-bg2: #d5c4a1;
    --gruvbox-bg3: #bdae93;
    --gruvbox-bg4: #a89984;

    --gruvbox-fg0: #282828;
    --gruvbox-fg1: #3c3836;
    --gruvbox-fg2: #504945;
    --gruvbox-fg3: #665c54;
    --gruvbox-fg4: #7c6f64;

    --gruvbox-gray: #928374;

    --gruvbox-red: #cc241d;
    --gruvbox-green: #98971a;
    --gruvbox-yellow: #d79921;
    --gruvbox-blue: #458588;
    --gruvbox-purple: #b16286;
    --gruvbox-aqua: #689d6a;
    --gruvbox-orange: #d65d0e;

    --gruvbox-red-faded: #9d0006;
    --gruvbox-green-faded: #79740e;
    --gruvbox-yellow-faded: #b57614;
    --gruvbox-blue-faded: #076678;
    --gruvbox-purple-faded: #8f3f71;
    --gruvbox-aqua-faded: #427b58;
    --gruvbox-orange-faded: #af3a03;

    /* Semantic tokens — change these to retheme without touching components.
       They reference only the --gruvbox-* slots, which palettes.css (loaded
       after this file) redefines for each palette but Gruvbox: keep it so. */
    --color-bg: var(--gruvbox-bg0);
    --color-surface: var(--gruvbox-bg0-hard);
    --color-border: var(--gruvbox-fg0);
    --color-text: var(--gruvbox-fg1);
    --color-text-strong: var(--gruvbox-fg3);
    --color-muted: var(--gruvbox-fg3);
    --color-link: var(--gruvbox-fg1);
    --color-link-hover: var(--gruvbox-blue-faded);
    --color-error: var(--gruvbox-red-faded);
    /* Empty part of progress bars. */
    --color-track: var(--gruvbox-bg1);
    /* Glyphs on an accent fill (app icons), the same in both schemes.
       palettes.css sets it for each palette. */
    --color-on-accent: #fbf1c7;

    --spacing: 1rem;
    --radius: 1rem;

    /* Form controls and scrollbars follow the palette in each scheme. */
    color-scheme: light;

    /* Gruvbox dark palette, held here and applied by the two blocks below
       (once for the OS preference, once for the explicit choice) so the
       values exist in exactly one place. The plain accents are the same in
       both schemes, as in Gruvbox itself; the "faded" slots, which this
       stylesheet uses for emphasis, take the dark scheme's bright variants. */
    --gruvbox-dark-bg0-hard: #1d2021;
    --gruvbox-dark-bg0: #282828;
    --gruvbox-dark-bg0-soft: #32302f;
    --gruvbox-dark-bg1: #3c3836;
    --gruvbox-dark-bg2: #504945;
    --gruvbox-dark-bg3: #665c54;
    --gruvbox-dark-bg4: #7c6f64;
    --gruvbox-dark-fg0: #fbf1c7;
    --gruvbox-dark-fg1: #ebdbb2;
    --gruvbox-dark-fg2: #d5c4a1;
    --gruvbox-dark-fg3: #bdae93;
    --gruvbox-dark-fg4: #a89984;
    --gruvbox-dark-red-bright: #fb4934;
    --gruvbox-dark-green-bright: #b8bb26;
    --gruvbox-dark-yellow-bright: #fabd2f;
    --gruvbox-dark-blue-bright: #83a598;
    --gruvbox-dark-purple-bright: #d3869b;
    --gruvbox-dark-aqua-bright: #8ec07c;
    --gruvbox-dark-orange-bright: #fe8019;
}

/* Dark scheme. The visitor's choice (`data-theme` on <html>, set from the
   `theme` cookie by the server and by the header toggle in the browser)
   beats the OS preference in both directions: the first block applies
   the OS's dark preference unless light was chosen, the second applies a
   dark choice regardless of the OS. The two must stay identical. */
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
        color-scheme: dark;
        --gruvbox-bg0-hard: var(--gruvbox-dark-bg0-hard);
        --gruvbox-bg0: var(--gruvbox-dark-bg0);
        --gruvbox-bg0-soft: var(--gruvbox-dark-bg0-soft);
        --gruvbox-bg1: var(--gruvbox-dark-bg1);
        --gruvbox-bg2: var(--gruvbox-dark-bg2);
        --gruvbox-bg3: var(--gruvbox-dark-bg3);
        --gruvbox-bg4: var(--gruvbox-dark-bg4);
        --gruvbox-fg0: var(--gruvbox-dark-fg0);
        --gruvbox-fg1: var(--gruvbox-dark-fg1);
        --gruvbox-fg2: var(--gruvbox-dark-fg2);
        --gruvbox-fg3: var(--gruvbox-dark-fg3);
        --gruvbox-fg4: var(--gruvbox-dark-fg4);
        --gruvbox-red-faded: var(--gruvbox-dark-red-bright);
        --gruvbox-green-faded: var(--gruvbox-dark-green-bright);
        --gruvbox-yellow-faded: var(--gruvbox-dark-yellow-bright);
        --gruvbox-blue-faded: var(--gruvbox-dark-blue-bright);
        --gruvbox-purple-faded: var(--gruvbox-dark-purple-bright);
        --gruvbox-aqua-faded: var(--gruvbox-dark-aqua-bright);
        --gruvbox-orange-faded: var(--gruvbox-dark-orange-bright);
        /* The page sits on bg1 rather than bg0, so controls on the darker
           surface stand out, and all text and borders take the brightest
           foreground. */
        --color-bg: var(--gruvbox-bg1);
        --color-text: var(--gruvbox-fg0);
        --color-text-strong: var(--gruvbox-fg0);
        --color-muted: var(--gruvbox-fg0);
        --color-link: var(--gruvbox-fg0);
        --color-border: var(--gruvbox-fg0);
        --color-track: var(--gruvbox-bg2);
    }
}

:root[data-theme="dark"] {
    color-scheme: dark;
    --gruvbox-bg0-hard: var(--gruvbox-dark-bg0-hard);
    --gruvbox-bg0: var(--gruvbox-dark-bg0);
    --gruvbox-bg0-soft: var(--gruvbox-dark-bg0-soft);
    --gruvbox-bg1: var(--gruvbox-dark-bg1);
    --gruvbox-bg2: var(--gruvbox-dark-bg2);
    --gruvbox-bg3: var(--gruvbox-dark-bg3);
    --gruvbox-bg4: var(--gruvbox-dark-bg4);
    --gruvbox-fg0: var(--gruvbox-dark-fg0);
    --gruvbox-fg1: var(--gruvbox-dark-fg1);
    --gruvbox-fg2: var(--gruvbox-dark-fg2);
    --gruvbox-fg3: var(--gruvbox-dark-fg3);
    --gruvbox-fg4: var(--gruvbox-dark-fg4);
    --gruvbox-red-faded: var(--gruvbox-dark-red-bright);
    --gruvbox-green-faded: var(--gruvbox-dark-green-bright);
    --gruvbox-yellow-faded: var(--gruvbox-dark-yellow-bright);
    --gruvbox-blue-faded: var(--gruvbox-dark-blue-bright);
    --gruvbox-purple-faded: var(--gruvbox-dark-purple-bright);
    --gruvbox-aqua-faded: var(--gruvbox-dark-aqua-bright);
    --gruvbox-orange-faded: var(--gruvbox-dark-orange-bright);
    /* The page sits on bg1 rather than bg0, so controls on the darker
       surface stand out, and all text and borders take the brightest
       foreground. */
    --color-bg: var(--gruvbox-bg1);
    --color-text: var(--gruvbox-fg0);
    --color-text-strong: var(--gruvbox-fg0);
    --color-muted: var(--gruvbox-fg0);
    --color-link: var(--gruvbox-fg0);
    --color-border: var(--gruvbox-fg0);
    --color-track: var(--gruvbox-bg2);
}

html {
    /* 100%, not smaller: anything else shrinks text on iOS in landscape. */
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
}

*,
*::before,
*::after {
    box-sizing: border-box;
}

/* Interface text is Figtree; prose (paragraphs, leads, descriptions) stays
   in the body's Recoleta. */
label,
input,
select,
textarea,
button,
.button,
.help,
.notice,
.error,
.badge,
.hint,
.facts,
.list,
.skip-link,
.card__meta,
.card__empty,
.day__date,
.archive__date,
.edition__meta,
.edition__nav,
.token {
    font-family: var(--font-ui);
}

body {
    margin: 0;
    min-height: 100vh;
    background: var(--color-bg);
    color: var(--color-text);
    font-family: var(--font-body);
    line-height: 1.5;
    display: flex;
    flex-direction: column;
}

a {
    color: var(--color-link);
}

a:hover {
    color: var(--color-link-hover);
}

a:focus-visible,
button:focus-visible,
input:focus-visible,
summary:focus-visible {
    outline: 2px solid var(--color-link-hover);
    outline-offset: 2px;
}

strong {
    font-family: var(--font-display);
    font-weight: normal;
}

.page {
    flex: 1;
    width: 100%;
    max-width: 900px;
    margin: 0 auto;
    padding: var(--spacing);
}

/* Site header, as on rhys.wtf, with this app's name beside the title. */
.site-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding-left: 1rem;
    padding-right: 1rem;
}

.site-header__brand {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 0 0.6rem;
    min-width: 0;
}

.site-header__title {
    font-family: var(--font-italic);
    font-size: 3rem;
    color: var(--color-text-strong);
    text-decoration: none;
}

.site-header__title:hover,
.site-header__app:hover {
    color: var(--color-text-strong);
    text-decoration: underline;
}

.site-header__app {
    font-family: var(--font-ui);
    font-size: 1.6rem;
    color: var(--color-muted);
    text-decoration: none;
}

/* Top right, the same in every rhys.wtf app: the apps mark, opening the
   apps menu with the light/dark switch at its foot. */
.site-header__actions {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

/* The apps mark: a rounded square per app in its Gruvbox colour, faded in
   light and bright in dark (the tokens flip). Profiles is red, feeds
   purple, dailies orange; later apps add squares. */
.apps-mark { width: 2rem; height: 2rem; display: block; }
.apps-mark__red { fill: var(--gruvbox-red-faded); }
.apps-mark__orange { fill: var(--gruvbox-orange-faded); }
.apps-mark__yellow { fill: var(--gruvbox-yellow-faded); }
.apps-mark__green { fill: var(--gruvbox-green-faded); }
.apps-mark__aqua { fill: var(--gruvbox-aqua-faded); }
.apps-mark__gray { fill: var(--gruvbox-gray); }
.apps-mark__blue { fill: var(--gruvbox-blue-faded); }
.apps-mark__purple { fill: var(--gruvbox-purple-faded); }

/* An app's icon: its favicon glyph on a square in its colour. */
.app-icon { width: 2rem; height: 2rem; flex: none; }
.app-icon__back { fill: var(--gruvbox-blue-faded); }
.app-icon--red .app-icon__back { fill: var(--gruvbox-red-faded); }
.app-icon--purple .app-icon__back { fill: var(--gruvbox-purple-faded); }
.app-icon--blue .app-icon__back { fill: var(--gruvbox-blue-faded); }
.app-icon--green .app-icon__back { fill: var(--gruvbox-green-faded); }
.app-icon--orange .app-icon__back { fill: var(--gruvbox-orange-faded); }
.app-icon--yellow .app-icon__back { fill: var(--gruvbox-yellow-faded); }
.app-icon--aqua .app-icon__back { fill: var(--gruvbox-aqua-faded); }
.app-icon--gray .app-icon__back { fill: var(--gruvbox-gray); }
/* The glyphs carry fill="#fbf1c7" for copies without this stylesheet;
   here they follow the palette. */
.app-icon g,
.app-icon text { fill: var(--color-on-accent); }
.app-icon [stroke]:not([stroke="none"]) { stroke: var(--color-on-accent); }

/* The app switcher: click the mark for a list of every app. A <details>,
   so it works without JavaScript; the browser bundle closes it on an
   outside click. */
.apps-menu { position: relative; }

.apps-menu__button {
    list-style: none;
    cursor: pointer;
    padding: 0.3rem;
    border-radius: 0.6rem;
    line-height: 0;
}

.apps-menu__button::-webkit-details-marker { display: none; }
.apps-menu__button:hover,
.apps-menu[open] .apps-menu__button { background: var(--color-surface); }
.apps-menu__button:focus-visible { outline: 2px solid var(--color-link-hover); }

.apps-menu__panel {
    position: absolute;
    right: 0;
    top: calc(100% + 0.4rem);
    z-index: 20;
    min-width: 17rem;
    padding: 0.5rem;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: 0 0.5rem 1.5rem rgba(0, 0, 0, 0.15);
}

.apps-menu__list { list-style: none; margin: 0; padding: 0; }

.apps-menu__item {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.5rem 0.6rem;
    border-radius: 0.6rem;
    text-decoration: none;
    color: var(--color-text);
}

.apps-menu__item:hover,
.apps-menu__item:focus-visible { background: var(--color-bg); }

.apps-menu__text { display: flex; flex-direction: column; min-width: 0; }
.apps-menu__name { font-family: var(--font-ui); font-size: 1.1rem; }
.apps-menu__desc { font-family: var(--font-ui); font-size: 0.9rem; color: var(--color-muted); }

/* The menu's last row, under a rule: the light/dark switch, laid out like
   an app (glyph in a 2rem box, then its name). The moon and "Dark mode"
   show in the light scheme, the sun and "Light mode" in the dark. */
.apps-menu__rule {
    border: 0;
    border-top: 1px solid var(--color-border);
    margin: 0.5rem 0.25rem;
}

.theme-toggle {
    margin: 0;
}

.theme-toggle__button {
    width: 100%;
    background: none;
    border: 0;
    font: inherit;
    text-align: left;
    cursor: pointer;
}

.theme-toggle__glyph {
    width: 2rem;
    height: 2rem;
    flex: none;
    display: grid;
    place-items: center;
    color: var(--color-text-strong);
}

.theme-toggle__icon,
.menu-icon {
    width: 1.5rem;
    height: 1.5rem;
    display: none;
}

.menu-icon,
.theme-toggle__icon--moon,
.theme-toggle__label--to-dark {
    display: block;
}

.theme-toggle__label--to-light {
    display: none;
}

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .theme-toggle__icon--moon,
    :root:not([data-theme="light"]) .theme-toggle__label--to-dark {
        display: none;
    }

    :root:not([data-theme="light"]) .theme-toggle__icon--sun,
    :root:not([data-theme="light"]) .theme-toggle__label--to-light {
        display: block;
    }
}

:root[data-theme="dark"] .theme-toggle__icon--moon,
:root[data-theme="dark"] .theme-toggle__label--to-dark {
    display: none;
}

:root[data-theme="dark"] .theme-toggle__icon--sun,
:root[data-theme="dark"] .theme-toggle__label--to-light {
    display: block;
}

.skip-link {
    position: absolute;
    left: -999px;
    top: 0;
    padding: 0.5rem 1rem;
    background: var(--color-surface);
    color: var(--color-text);
    border: 1px solid var(--color-border);
    z-index: 10;
}

.skip-link:focus {
    left: 1rem;
    top: 1rem;
}

/* Home hero, as rhys.wtf's greeting. */
.greeting {
    text-align: center;
    margin: 2rem 0 3rem;
}

.greeting__hello {
    font-family: var(--font-display);
    font-size: clamp(3rem, 12vw, 6rem);
    font-weight: normal;
    color: var(--color-text-strong);
    margin: 0;
    line-height: 1;
}

.greeting__welcome {
    font-family: var(--font-body);
    font-size: clamp(1.5rem, 5vw, 2.5rem);
    color: var(--color-text-strong);
    margin: 0.5rem 0 0;
}

.lead {
    font-size: 1.2rem;
}

/* Section heading: title and rule. */
.section-header {
    margin-bottom: 1rem;
}

.section-header__title {
    font-family: var(--font-display);
    font-size: 2rem;
    font-weight: normal;
    color: var(--color-text-strong);
    margin: 0 0 -0.25rem 0;
}

.section-header__rule {
    border: 0;
    border-top: 1px solid var(--color-border);
    margin: 0;
}

/* Sign-in-sized pages: rhys.wtf's login column. */
.narrow {
    max-width: 24rem;
    margin: 2rem auto;
}

.narrow__title,
.page-title {
    font-family: var(--font-display);
    font-weight: normal;
    margin: 0 0 1rem 0;
}

.page-title {
    font-size: 2.5rem;
    color: var(--color-text-strong);
}

.narrow-form {
    max-width: 24rem;
}

.form {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    margin: 0 0 1rem;
}

.field {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}

input[type="text"],
input[type="email"],
input[type="password"],
input[type="number"],
input[type="time"],
select,
textarea {
    width: 100%;
    min-width: 0;
    padding: 0.5rem;
    font-size: 1rem;
    font-family: var(--font-ui);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-surface);
    color: var(--color-text);
}

.prefixed {
    display: flex;
    align-items: stretch;
}

/* The prefix keeps its width and stays on one line ("/d/" would
   otherwise break at each slash); the input takes the rest of the row. */
.prefixed__prefix {
    flex: none;
    white-space: nowrap;
    display: flex;
    align-items: center;
    padding: 0 0.6rem;
    border: 1px solid var(--color-border);
    border-right: 0;
    border-radius: var(--radius) 0 0 var(--radius);
    background: var(--gruvbox-bg0-soft);
    color: var(--color-muted);
}

.prefixed input {
    flex: 1;
    width: auto;
    border-radius: 0 var(--radius) var(--radius) 0;
}

.help {
    font-size: 0.95rem;
    color: var(--color-muted);
    margin: 0;
}

.help:empty {
    display: none;
}

/* Buttons: rhys.wtf's outlined pills. */
.button {
    display: block;
    width: 100%;
    text-align: center;
    padding: 0.5rem 1rem;
    font-family: var(--font-ui);
    font-size: 1rem;
    line-height: 1.5;
    background: var(--color-surface);
    color: var(--color-text);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    text-decoration: none;
    cursor: pointer;
}

.button:hover {
    background: var(--gruvbox-bg0-soft);
    color: var(--color-text);
}

.button:disabled {
    opacity: 0.55;
    cursor: progress;
}

.button--small {
    display: inline-block;
    width: auto;
    padding: 0.35rem 0.75rem;
}

.button--danger {
    border-color: var(--color-error);
    color: var(--color-error);
}

.button--danger:hover {
    background: var(--color-error);
    color: var(--color-bg);
}

.actions {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.rule {
    margin: 1.5rem 0;
    border: none;
    border-top: 1px solid var(--color-border);
}

.hint {
    margin-top: 1.25rem;
}

details summary {
    cursor: pointer;
    text-decoration: underline;
    margin: 0.5rem 0;
}

details[open] summary {
    margin-bottom: 0.75rem;
}

/* Messages: rhys.wtf's .error box, and a neutral twin. */
.error,
.notice {
    padding: 0.5rem var(--spacing);
    border: 1px solid var(--color-error);
    border-radius: var(--radius);
    margin: 0 0 1rem;
}

/* On the surface, not the page: in the dark schemes the bright reds
   only pass AA on the darker surface (Gruvbox's #fb4934 is 3.4:1 on its
   dark page, 4.8:1 on the surface). */
.error {
    color: var(--color-error);
    background: var(--color-surface);
}

.notice {
    border-color: var(--color-border);
    background: var(--color-surface);
}

.error p,
.notice p {
    margin: 0.25rem 0;
}

/* A share link shown once: long, and with no spaces to break at. */
.notice .token {
    overflow-wrap: anywhere;
}

.list {
    list-style: none;
    margin: 0 0 1rem;
    padding: 0;
}

.list__item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.6rem 0;
    border-bottom: 1px solid var(--color-border);
}

.list__item form {
    margin: 0;
}

/* Site footer, as on rhys.wtf: the one place outside the type system's
   rules, in Recoleta like the rest of rhys.wtf's footer, links and
   sign-out button included. */
.site-footer {
    font-family: var(--font-body);
    text-align: center;
    font-size: 1.2rem;
    padding: 0 var(--spacing) 1rem;
    width: 100%;
}

.site-footer__rule {
    border: 0;
    border-top: 1px solid var(--color-border);
    width: 30%;
}

.site-footer__links {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0 0.5rem;
}

.site-footer__links li + li::before {
    content: "⁕";
    margin-right: 0.5rem;
}

.site-footer__link {
    font-size: 1.3rem;
    text-decoration: underline;
}

.site-footer__form {
    display: inline;
    margin: 0;
}

.site-footer__button {
    font-family: var(--font-body);
    color: var(--color-link);
    background: none;
    border: 0;
    padding: 0;
    cursor: pointer;
}

.site-footer__button:hover {
    color: var(--color-link-hover);
}

.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
}

@media (max-width: 30rem) {
    .site-header__title {
        font-size: 2.4rem;
    }

    .site-header__app {
        font-size: 1.3rem;
    }

    .facts {
        grid-template-columns: 1fr;
    }

    .facts dd {
        margin-bottom: 0.4rem;
    }
}

/* ------------------------------------------------------------------ */
/* Lists, as on Diagrams' list page: a breadcrumb, the title with the
   view switch, the tools, then cards or rows with a "…" each.          */

label.small,
.small {
    font-size: 0.8rem;
    color: var(--color-muted);
}

.list-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    margin-bottom: 0.75rem;
}

.list-head .page-title {
    min-width: 0;
    margin: 0;
    overflow-wrap: anywhere;
}

.list-head__end {
    display: flex;
    align-items: center;
    gap: 0.75rem 1rem;
    flex-wrap: wrap;
    font-family: var(--font-ui);
}

.list-intro {
    margin: -0.25rem 0 1.25rem;
    color: var(--color-muted);
}

.breadcrumbs {
    font-family: var(--font-ui);
    margin-bottom: 0.25rem;
}

.breadcrumbs ol {
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    gap: 0.1rem 0.4rem;
    margin: 0;
    padding: 0;
}

.breadcrumbs li {
    min-width: 0;
    overflow-wrap: anywhere;
}

.breadcrumbs li + li::before {
    content: "›" / "";
    margin-right: 0.4rem;
    color: var(--color-muted);
}

.breadcrumbs [aria-current] {
    color: var(--color-muted);
}

.list-tools {
    /* The pop-ups below anchor here, not to their buttons, so they fit
       a phone's width. */
    position: relative;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem 1rem;
    flex-wrap: wrap;
    margin-bottom: 1.25rem;
}

.list-tools__new {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.list-tools form {
    margin: 0;
}

/* Grid or list: two buttons in one outlined pill. */
.view-switch {
    display: inline-flex;
    margin: 0;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    overflow: hidden;
    background: var(--color-surface);
}

.view-switch__button {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0.35rem 0.65rem;
    border: 0;
    background: transparent;
    color: var(--color-text);
    cursor: pointer;
}

.view-switch__button + .view-switch__button {
    border-left: 1px solid var(--color-border);
}

.view-switch__button:hover {
    background: var(--gruvbox-bg0-soft);
}

.view-switch__button[aria-pressed="true"] {
    background: var(--color-text);
    color: var(--color-surface);
}

.view-switch__button:focus-visible {
    outline: 2px solid var(--color-link-hover);
    outline-offset: -3px;
}

/* Pop-ups: Upload, New folder and every item's "…". */
.share__panel {
    position: absolute;
    left: 0;
    top: calc(100% + 0.4rem);
    z-index: 25;
    width: min(24rem, 90vw);
    padding: 1rem;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: 0 0.5rem 1.5rem rgba(0, 0, 0, 0.15);
}

.share__panel p {
    margin: 0 0 0.75rem;
}

.new-folder,
.item-menu {
    position: relative;
}

.new-folder {
    position: static;
}

.new-folder > summary,
.new-folder[open] > summary,
.item-menu > summary,
.item-menu[open] > summary {
    list-style: none;
    text-decoration: none;
    margin: 0;
}

.new-folder > summary::-webkit-details-marker,
.item-menu > summary::-webkit-details-marker,
.item-menu__confirm > summary::-webkit-details-marker {
    display: none;
}

.new-folder .share__panel {
    left: 0;
    width: min(22rem, 100%);
}

.upload .upload__panel {
    width: min(26rem, 100%);
}

.item-menu__button,
.item-link,
.item-end {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 2.1rem;
    height: 2.1rem;
    border: 1px solid transparent;
    border-radius: 50%;
    font-family: var(--font-ui);
    font-size: 1.2rem;
    line-height: 1;
    cursor: pointer;
    color: var(--color-text);
    flex: none;
}

.item-menu__button:hover,
.item-menu[open] > .item-menu__button,
.item-link:hover {
    border-color: var(--color-border);
    background: var(--color-bg);
    color: var(--color-text);
}

.item-menu__button:focus-visible {
    outline: 2px solid var(--color-link-hover);
}

.item-menu > .item-menu__panel {
    left: auto;
    right: 0;
    width: min(20rem, calc(100vw - 2rem));
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    font-family: var(--font-ui);
    cursor: auto;
}

/* Opened near the bottom of the window, upwards (the browser bundle
   decides: web/src/lib.rs). */
.item-menu--up > .item-menu__panel {
    top: auto;
    bottom: calc(100% + 0.4rem);
}

.item-menu__links {
    display: flex;
    gap: 1.25rem;
}

.item-menu__open {
    font-family: var(--font-ui);
}

.item-menu__form {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    margin: 0;
}

.item-menu__row {
    display: flex;
    gap: 0.5rem;
    align-items: center;
}

.item-menu__row input {
    flex: 1;
    padding: 0.3rem 0.75rem;
}

.item-menu__form select {
    padding: 0.35rem 0.5rem;
}

.item-menu__confirm > summary {
    margin: 0;
    color: var(--color-error);
}

.item-menu__confirm[open] > summary {
    margin-bottom: 0.5rem;
}

.item-menu__confirm form {
    margin: 0;
}

.item-menu__panel p {
    margin: 0 0 0.6rem;
}

.move-page {
    margin: 1rem 0;
}

/* The items, in whichever view. An open menu sits above everything
   after it. */
.items {
    list-style: none;
    margin: 0 0 2rem;
    padding: 0;
}

.item {
    position: relative;
    min-width: 0;
}

.item:has(.item-menu[open]) {
    z-index: 30;
}

.badge {
    font-family: var(--font-ui);
    font-size: 0.8rem;
    color: var(--gruvbox-aqua-faded);
    border: 1px solid currentColor;
    border-radius: var(--radius);
    padding: 0 0.5rem;
    white-space: nowrap;
}

.badge--public {
    color: var(--gruvbox-purple-faded);
}

/* Notes' folders that are published as posts, in Posts' green. */
.badge--posts {
    color: var(--gruvbox-green-faded);
}

/* Public or private, in a "…" menu: "Make public…" asks first, as
   Delete… does, but it's not a danger, so it's in the link colour. */
.item-menu__visibility {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

.item-menu__visibility p {
    margin: 0;
}

.item-menu__confirm--public > summary {
    color: var(--color-link);
}

/* Public addresses are long and have no spaces: they wrap anywhere. */
.public-address {
    overflow-wrap: anywhere;
    font-size: 0.9rem;
}

p.public-address {
    padding: 0.35rem 0.5rem;
    border: 1px solid var(--color-border);
    border-radius: 0.5rem;
    background: var(--color-bg);
    font-family: var(--font-ui);
}

/* On a public folder's own page: what it is, and "Make private"; and
   where something just went in the trash, Undo. */
.visibility-notice,
.undo-notice {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem 1rem;
    flex-wrap: wrap;
    font-family: var(--font-ui);
}

.visibility-notice form,
.undo-notice form {
    margin: 0;
}

/* On a Notes folder's own page: "Publish this folder as posts", the box
   Notes has, its form sent on to Notes. */
.posts-box {
    margin: 0 0 1.25rem;
    padding: 0.25rem var(--spacing);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-surface);
    font-family: var(--font-ui);
}

/* Not underlined: the badge in it would be too. */
.posts-box > summary,
.posts-box[open] > summary {
    margin: 0.4rem 0;
    text-decoration: none;
}

.posts-box > .help {
    margin: 0 0 0.5rem;
}

.posts-box__form {
    max-width: 28rem;
    margin: 0.75rem 0 0.75rem;
}

.check {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.check input {
    width: 1.1rem;
    height: 1.1rem;
    margin: 0;
}

.make-public .share__panel {
    left: 0;
    width: min(24rem, 100%);
}

/* Grid: cards, the "…" in the bottom-right corner, beside the meta. The
   bar along the top says what sort of thing it is: folders yellow,
   diagrams aqua, pictures green, and so on. */
.tiles {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(15rem, 100%), 1fr));
    gap: 1rem;
}

.tile {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    height: 100%;
    padding: 1rem 1.25rem;
    border: 1px solid var(--color-border);
    border-top: 0.4rem solid var(--gruvbox-fg4);
    border-radius: var(--radius);
    background: var(--color-surface);
    color: var(--color-text);
    text-decoration: none;
}

.tile--folder,
.tile--yellow { border-top-color: var(--gruvbox-yellow-faded); }
.tile--diagram,
.tile--aqua { border-top-color: var(--gruvbox-aqua-faded); }
.tile--image,
.tile--green { border-top-color: var(--gruvbox-green-faded); }
.tile--video,
.tile--purple { border-top-color: var(--gruvbox-purple-faded); }
.tile--audio,
.tile--orange { border-top-color: var(--gruvbox-orange-faded); }
.tile--document,
.tile--link,
.tile--blue { border-top-color: var(--gruvbox-blue-faded); }
.tile--archive,
.tile--red { border-top-color: var(--gruvbox-red-faded); }

.tile__thumb {
    display: block;
    aspect-ratio: 16 / 9;
    margin-bottom: 0.4rem;
    overflow: hidden;
    border: 1px solid var(--color-border);
    border-radius: calc(var(--radius) / 2);
    background: var(--color-track);
}

.tile__thumb picture,
.row__icon picture {
    display: block;
    width: 100%;
    height: 100%;
}

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

/* A portrait diagram's page, 3:4, whole. */
.tile__thumb--portrait {
    aspect-ratio: 3 / 4;
}

/* Each row of cards shares three tracks, pictures, titles and details,
   so a 16:9 picture beside a 3:4 one stands at the foot of the taller
   track, on its title, and the titles line up. */
.items--grid > .item {
    display: grid;
    grid-row: span 3;
    grid-template-rows: subgrid;
}

.items--grid .tile {
    display: grid;
    grid-row: span 3;
    grid-template-rows: subgrid;
    row-gap: 0.4rem;
}

.items--grid .tile__thumb {
    align-self: end;
}

.tile__thumb--icon,
.tile__thumb--app {
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--color-bg);
}

.tile__app-icon .app-icon {
    width: 4.5rem;
    height: 4.5rem;
}

.tile__title {
    font-family: var(--font-display);
    font-size: 1.3rem;
    text-decoration: underline;
    text-underline-offset: 0.12em;
    overflow-wrap: anywhere;
}

a.tile:hover .tile__title {
    color: var(--color-link-hover);
}

.tile__meta {
    font-family: var(--font-ui);
    font-size: 0.95rem;
    color: var(--color-muted);
}

.items--grid .item-menu,
.items--grid .item-link {
    position: absolute;
    right: 0.75rem;
    bottom: 0.7rem;
}

.items--grid .tile__meta {
    padding-right: 2.25rem;
}

/* A type's icon where there's no thumbnail, in its sort's colour, with
   the extension under it on cards. */
.type-icon {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.2rem;
    color: var(--gruvbox-fg4);
}

.type-icon__ext {
    font-family: var(--font-ui);
    font-size: 0.75rem;
    letter-spacing: 0.08em;
    color: var(--color-muted);
}

.item--folder .type-icon { color: var(--gruvbox-yellow-faded); }
.item--diagram .type-icon { color: var(--gruvbox-aqua-faded); }
.item--image .type-icon { color: var(--gruvbox-green-faded); }
.item--video .type-icon { color: var(--gruvbox-purple-faded); }
.item--audio .type-icon { color: var(--gruvbox-orange-faded); }
.item--document .type-icon,
.item--link .type-icon { color: var(--gruvbox-blue-faded); }
.item--archive .type-icon { color: var(--gruvbox-red-faded); }

/* List: rows under a rule. */
.row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    border-bottom: 1px solid var(--color-border);
}

.items--list .row:first-child {
    border-top: 1px solid var(--color-border);
}

.row__link {
    flex: 1;
    min-width: 0;
    display: grid;
    align-items: center;
    gap: 0 1rem;
    padding: 0.5rem 0.25rem;
    color: var(--color-text);
    text-decoration: none;
    font-family: var(--font-ui);
}

.items--list .row__link {
    grid-template-columns: 4rem minmax(0, 1fr) 10.5rem 5rem 7rem 8.5rem;
}

.row__title {
    min-width: 0;
    font-family: var(--font-ui);
    font-size: 1.05rem;
    text-decoration: underline;
    text-underline-offset: 0.12em;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

a.row__link:hover .row__title {
    color: var(--color-link-hover);
}

.row__kind,
.row__size,
.row__edited {
    color: var(--color-muted);
    font-size: 0.95rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.row__size {
    text-align: right;
}

.row__meta {
    display: contents;
}

.row__icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 4rem;
    height: 2.25rem;
    overflow: hidden;
    border-radius: 0.35rem;
}

.row__icon--thumb {
    border: 1px solid var(--color-border);
    background: var(--color-track);
}

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

/* A portrait diagram's: as tall, 3:4, in the middle of its column
   (4rem, or 3rem when narrow). */
.items .row__icon.row__icon--portrait {
    width: 1.6875rem;
    justify-self: center;
}

.row__app-icon .app-icon {
    width: 2rem;
    height: 2rem;
}

/* My files' space: a bar and how much of it is used, and the trash. */
.usage {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.6rem;
    font-family: var(--font-ui);
    font-size: 0.95rem;
    color: var(--color-muted);
}

.usage__meter {
    width: 9rem;
    height: 0.7rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-track);
    overflow: hidden;
    -webkit-appearance: none;
    appearance: none;
}

.usage__meter::-webkit-meter-bar {
    background: var(--color-track);
    border: 0;
    border-radius: var(--radius);
}

.usage__meter::-webkit-meter-optimum-value,
.usage__meter::-webkit-meter-suboptimum-value,
.usage__meter::-webkit-meter-even-less-good-value {
    border-radius: var(--radius);
}

.usage__meter::-webkit-meter-optimum-value { background: var(--gruvbox-yellow-faded); }
.usage__meter::-webkit-meter-suboptimum-value { background: var(--gruvbox-orange-faded); }
.usage__meter::-webkit-meter-even-less-good-value { background: var(--gruvbox-red-faded); }
.usage__meter::-moz-meter-bar { background: var(--gruvbox-yellow-faded); }
.usage__meter:-moz-meter-sub-optimum::-moz-meter-bar { background: var(--gruvbox-orange-faded); }
.usage__meter:-moz-meter-sub-sub-optimum::-moz-meter-bar { background: var(--gruvbox-red-faded); }

/* The upload form, and the browser bundle's progress under it, a row per
   file. */
.upload-form__files {
    font-family: var(--font-ui);
    font-size: 0.95rem;
    max-width: 100%;
}

.upload-form__files::file-selector-button {
    font: inherit;
    padding: 0.3rem 0.75rem;
    margin-right: 0.6rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-bg);
    color: var(--color-text);
    cursor: pointer;
}

.share__panel .upload-form__limits {
    font-family: var(--font-ui);
    margin: 0.2rem 0 0.4rem;
    font-size: 0.9rem;
    color: var(--color-muted);
}

.upload-form__progress {
    font-family: var(--font-ui);
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

.upload-form__progress:empty {
    display: none;
}

.upload-form__file {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 0.1rem 0.5rem;
    font-size: 0.9rem;
}

.upload-form__name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.upload-form__state {
    color: var(--color-muted);
}

.upload-form__file progress {
    grid-column: 1 / -1;
    width: 100%;
    height: 0.5rem;
    accent-color: var(--gruvbox-yellow-faded);
}

.upload-form__file--failed .upload-form__state {
    color: var(--color-error);
}

/* A drop's own lines in the progress list: where its files are going
   ("In Holiday / Photos"), and why it, or a folder in it, couldn't go. */
.upload-form__note {
    font-size: 0.9rem;
    color: var(--color-muted);
}

.upload-form__note--failed {
    color: var(--color-error);
}

/* Drag and drop (the browser bundle, web/src/dnd.rs): while files from
   the desktop are dragged over a folder of one's own, its listing is
   outlined and tinted, or the subfolder under the pointer is instead,
   and the label at the foot of the window (a live region) says where
   they'll go. Outlines and shadows, never padding or borders, so
   nothing under the pointer moves. */
.drop-zone {
    border-radius: var(--radius);
}

.drop-zone--active {
    outline: 2px dashed var(--gruvbox-yellow-faded);
    outline-offset: 0.5rem;
    background: color-mix(in srgb, var(--gruvbox-yellow-faded) 12%, transparent);
    box-shadow: 0 0 0 0.5rem color-mix(in srgb, var(--gruvbox-yellow-faded) 12%, transparent);
}

/* An empty folder's listing is short: the target is a decent size, its
   words further in from the edge. */
.drop-zone--active:has(> .empty) {
    min-height: 10rem;
    outline-offset: 1rem;
    box-shadow: 0 0 0 1rem color-mix(in srgb, var(--gruvbox-yellow-faded) 12%, transparent);
}

.drop-zone--sub {
    outline: 2px dashed color-mix(in srgb, var(--gruvbox-yellow-faded) 45%, transparent);
    outline-offset: 0.5rem;
}

.drop-target--active .tile,
.items--list .drop-target--active {
    outline: 3px solid var(--gruvbox-yellow-faded);
    outline-offset: 2px;
    background: color-mix(in srgb, var(--gruvbox-yellow-faded) 22%, var(--color-surface));
}

.items--list .drop-target--active {
    border-radius: 0.4rem;
}

.drop-label {
    position: fixed;
    left: 50%;
    bottom: 1.5rem;
    z-index: 100;
    transform: translateX(-50%);
    max-width: calc(100% - 2rem);
    box-sizing: border-box;
    padding: 0.6rem 1.2rem;
    border: 2px solid var(--gruvbox-yellow-faded);
    border-radius: var(--radius);
    background: var(--color-surface);
    color: var(--color-text);
    font-family: var(--font-ui);
    font-size: 1rem;
    overflow-wrap: anywhere;
    text-align: center;
    box-shadow: 0 0.4rem 1.2rem rgb(0 0 0 / 0.25);
    pointer-events: none;
}

/* Empty, it's still there (a live region must be, to be read out when it
   speaks), only nothing to see. */
.drop-label:empty {
    padding: 0;
    border: 0;
    box-shadow: none;
}

.empty {
    margin: 2rem 0;
}

.inline-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.inline-actions form {
    margin: 0;
}

.narrow__subtitle {
    font-family: var(--font-display);
    font-weight: normal;
    font-size: 1.4rem;
    margin: 0 0 0.5rem;
}

@media (max-width: 40rem) {
    /* Narrow: the title on its own line, the details under it. */
    .items--list .row__link {
        grid-template-columns: 3rem minmax(0, 1fr);
    }

    .items--list .row__icon {
        grid-row: span 2;
        width: 3rem;
    }

    .items--list .row__meta {
        display: flex;
        flex-wrap: wrap;
        gap: 0 0.6rem;
        align-items: center;
    }

    .row__size {
        text-align: left;
    }

    .items--list .row__size:empty,
    .items--list .row__edited:empty,
    .items--list .row__badges:empty {
        display: none;
    }

    .usage__meter {
        width: 6rem;
    }
}

/* The trash: an entry a row, what it is on the left, Restore and
   "Delete forever…" on the right (under it, when narrow). */
.trash__item {
    flex-wrap: wrap;
    align-items: flex-start;
}

.trash__what {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
    flex: 1 1 18rem;
    min-width: 0;
}

.trash__icon {
    flex: none;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 2.5rem;
    height: 2.25rem;
}

.trash__text {
    display: flex;
    flex-direction: column;
    min-width: 0;
    gap: 0.15rem;
}

.trash__name {
    font-family: var(--font-ui);
    font-size: 1.05rem;
    overflow-wrap: anywhere;
}

.trash__meta {
    font-family: var(--font-ui);
    font-size: 0.9rem;
}

.trash__actions {
    display: flex;
    align-items: flex-start;
    flex-wrap: wrap;
    gap: 0.5rem 1rem;
    font-family: var(--font-ui);
}

.trash__actions form,
.trash__empty form {
    margin: 0;
}

.trash__actions .item-menu__confirm,
.trash__empty {
    max-width: 20rem;
    font-family: var(--font-ui);
}

.trash__actions .item-menu__confirm > summary,
.trash__empty > summary {
    margin: 0.35rem 0 0;
}

.trash__actions .item-menu__confirm p,
.trash__empty p {
    margin: 0 0 0.5rem;
}

/* Above an admin's view of someone's files (`admin_view.rs`): whose they
   are, that it's read-only and recorded. */
.admin-banner {
    margin: 0 0 1rem;
    padding: .6rem 1rem;
    border: 2px solid var(--color-error);
    border-radius: 1rem;
    background: var(--color-surface);
    color: var(--color-text);
    font-family: var(--font-ui);
    font-weight: bold;
}
