/* links.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 dailies'
   static/main.css (from profiles', itself from rhyswtf-rs/style/main.css):
   keep them in step. Links' 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 script; the browser bundle (web/) closes it on an
   outside click or Escape. */
.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;
}

.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;
    }
}

/* ------------------------------------------------------------------ */
/* Links' own parts. Links is blue: --gruvbox-blue-faded.               */

.badge,
.card__site,
.card__meta,
.cloud,
.tags,
.summary,
.snippet,
.row__host,
.row__date,
.row__details,
.pagination,
.tag-row,
.view-switch,
.search,
.add,
.check,
.bookmarklet {
    font-family: var(--font-ui);
}

.page--wide {
    max-width: 1240px;
}

.prose {
    max-width: 44rem;
    margin: 1.5rem auto 0;
}

.prose p {
    margin: 0 0 1rem;
}

.section-title {
    font-family: var(--font-display);
    font-weight: normal;
    font-size: 1.6rem;
    color: var(--color-text-strong);
    margin: 2.25rem 0 0.75rem;
}

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

textarea.textarea--short {
    min-height: 4.5rem;
}

input[type="search"] {
    width: 100%;
    min-width: 0;
    padding: 0.5rem 0.75rem;
    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);
}

input[type="file"] {
    font-family: var(--font-ui);
    max-width: 100%;
}

select:focus-visible,
textarea:focus-visible {
    outline: 2px solid var(--color-link-hover);
    outline-offset: 2px;
}

mark {
    background: color-mix(in srgb, var(--gruvbox-yellow) 42%, transparent);
    color: inherit;
    border-radius: 0.2em;
    padding: 0 0.08em;
}

/* The search box, at the top of every page. */
.search {
    display: flex;
    gap: 0.5rem;
    align-items: stretch;
    margin: 0.25rem 0 1rem;
}

.search input[type="search"] {
    flex: 1 1 14rem;
}

.search select {
    width: auto;
    flex: 0 0 auto;
}

/* Adding a link: an address and Save, the rest folded away. */
.add {
    margin: 0 0 1.5rem;
    padding: 0.75rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-surface);
}

.add__row {
    display: flex;
    gap: 0.5rem;
}

.add__row input {
    flex: 1;
}

.add__more {
    margin-top: 0.25rem;
}

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

.add__fields {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.75rem;
    margin-top: 0.5rem;
}

.add .error,
.add .notice {
    margin-bottom: 0.75rem;
}

/* The library: tags beside the links (above them on phones). */
.library {
    display: grid;
    grid-template-columns: 13rem minmax(0, 1fr);
    gap: 2rem;
    align-items: start;
}

.tagbar {
    position: sticky;
    top: 1rem;
    max-height: calc(100vh - 2rem);
    overflow-y: auto;
    padding-right: 0.25rem;
}

.tagbar__title {
    font-family: var(--font-display);
    font-weight: normal;
    font-size: 1.3rem;
    color: var(--color-text-strong);
    margin: 0.2rem 0 0.6rem;
}

.tagbar-mobile {
    display: none;
}

.tagbar__manage {
    font-family: var(--font-ui);
    font-size: 0.9rem;
    margin: 1rem 0 0;
}

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

.cloud {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
}

.cloud__tag {
    display: inline-flex;
    align-items: baseline;
    gap: 0.35rem;
    padding: 0.15rem 0.6rem;
    border: 1px solid var(--color-border);
    border-radius: 999px;
    font-size: 0.9rem;
    text-decoration: none;
    background: var(--color-surface);
    color: var(--color-text);
}

.cloud__tag:hover {
    color: var(--color-link-hover);
    border-color: var(--color-link-hover);
}

.cloud__count {
    font-size: 0.78rem;
    color: var(--color-muted);
}

.cloud__tag--on {
    background: var(--gruvbox-blue-faded);
    border-color: var(--gruvbox-blue-faded);
    color: var(--gruvbox-bg0);
}

.cloud__tag--on .cloud__count {
    color: inherit;
    opacity: 0.85;
}

.cloud__tag--on::after {
    content: "×";
    margin-left: 0.1rem;
}

.cloud__tag--on:hover {
    color: var(--gruvbox-bg0);
    opacity: 0.9;
}

.toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem 1rem;
    margin: 0 0 1rem;
}

.summary {
    margin: 0;
    color: var(--color-muted);
}

.summary strong {
    font-family: var(--font-ui);
    color: var(--color-text);
}

.empty {
    padding: 2rem 1rem;
    text-align: center;
    border: 1px dashed var(--color-border);
    border-radius: var(--radius);
}

/* The view switch, as in Diagrams. */
.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;
    gap: 0.35rem;
    padding: 0.35rem 0.7rem;
    border: 0;
    background: transparent;
    color: var(--color-text);
    font: inherit;
    font-size: 0.95rem;
    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;
}

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

/* Favicons: the site's own, or its initial. */
.favicon {
    display: inline-block;
    flex: none;
    width: 1rem;
    height: 1rem;
    border-radius: 0.2rem;
    object-fit: contain;
    vertical-align: middle;
}

.favicon-picture {
    display: inline-flex;
    flex: none;
}

.favicon--letter {
    display: inline-grid;
    place-items: center;
    background: var(--gruvbox-blue-faded);
    color: var(--gruvbox-bg0);
    font-family: var(--font-ui);
    font-size: 0.65rem;
    line-height: 1;
}

/* Cards: the picture, then the words. The title's link covers the whole
   card, so a click anywhere opens the source; tags and Details sit
   above it. */
.items {
    list-style: none;
    margin: 0;
    padding: 0;
}

.items--cards {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(17.5rem, 100%), 1fr));
    gap: 1.25rem;
}

.card {
    position: relative;
    display: flex;
    flex-direction: column;
    min-width: 0;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-surface);
    overflow: hidden;
}

.card:hover,
.card:focus-within {
    border-color: var(--color-link-hover);
}

.card__thumb {
    aspect-ratio: 640 / 336;
    background: var(--gruvbox-bg1);
    border-bottom: 1px solid var(--color-border);
    overflow: hidden;
}

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

.card__placeholder {
    height: 100%;
    display: grid;
    place-items: center;
    padding: 1rem;
    background:
        linear-gradient(135deg, color-mix(in srgb, var(--gruvbox-blue-faded) 22%, transparent), transparent 70%),
        var(--gruvbox-bg0-soft);
    color: var(--gruvbox-blue-faded);
    font-family: var(--font-display);
    font-size: 1.35rem;
    text-align: center;
    overflow-wrap: anywhere;
}

.card__placeholder--pending span {
    opacity: 0.55;
}

.card__body {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    flex: 1;
    padding: 0.8rem 1rem 0.9rem;
    min-width: 0;
}

.card__site {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    margin: 0;
    font-size: 0.88rem;
    color: var(--color-muted);
    min-width: 0;
}

.card__site-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.card__title {
    font-family: var(--font-display);
    font-weight: normal;
    font-size: 1.18rem;
    line-height: 1.25;
    margin: 0;
    overflow-wrap: anywhere;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.card__link {
    color: var(--color-text-strong);
    text-decoration: none;
}

.card__link::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 1;
}

.card__link:hover,
.card:hover .card__link {
    color: var(--color-link-hover);
}

.card__link:focus-visible {
    outline: none;
}

.card:has(.card__link:focus-visible) {
    outline: 2px solid var(--color-link-hover);
    outline-offset: 2px;
}

.card__description {
    margin: 0;
    font-size: 0.98rem;
    line-height: 1.45;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
    overflow-wrap: anywhere;
}

.card__meta {
    margin: auto 0 0;
    padding-top: 0.35rem;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.3rem 0.75rem;
    font-size: 0.88rem;
    color: var(--color-muted);
}

.card__details,
.row__details {
    position: relative;
    z-index: 2;
    margin-left: auto;
}

.snippet {
    margin: 0;
    font-size: 0.9rem;
    line-height: 1.4;
    color: var(--color-text);
    overflow-wrap: anywhere;
}

.snippet__label {
    color: var(--color-muted);
}

.tags {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
    position: relative;
    z-index: 2;
}

.tag {
    display: inline-block;
    padding: 0.05rem 0.5rem;
    border-radius: 999px;
    font-size: 0.82rem;
    text-decoration: none;
    color: var(--gruvbox-blue-faded);
    background: color-mix(in srgb, var(--gruvbox-blue-faded) 12%, transparent);
}

.tag:hover {
    color: var(--gruvbox-bg0);
    background: var(--gruvbox-blue-faded);
}

.badge {
    display: inline-block;
    padding: 0.05rem 0.5rem;
    border-radius: 999px;
    border: 1px dashed var(--color-muted);
    font-size: 0.8rem;
    color: var(--color-muted);
}

/* On the surface, like .error: in a row it sits on the page, where the
   dark schemes' bright reds fall short of AA. */
.badge--status {
    border-style: solid;
    border-color: var(--color-error);
    color: var(--color-error);
    background: var(--color-surface);
}

/* The compact list. Its rows answer to the list's own width, not the
   screen's: below 48rem there isn't room for a readable title beside the
   tags, date and actions (up to 24rem), so those go under the title. */
.items--list {
    border-top: 1px solid var(--color-border);
    container-type: inline-size;
}

.row {
    display: grid;
    grid-template-columns: 1.5rem minmax(0, 1fr) auto;
    gap: 0.25rem 0.75rem;
    align-items: start;
    padding: 0.55rem 0;
    border-bottom: 1px solid var(--color-border);
}

.row__icon {
    padding-top: 0.2rem;
}

.row__icon .favicon {
    width: 1.25rem;
    height: 1.25rem;
}

.row__icon .favicon--letter {
    font-size: 0.75rem;
}

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

.row__title {
    font-family: var(--font-display);
    font-size: 1.05rem;
    color: var(--color-text-strong);
    text-decoration: none;
    overflow-wrap: anywhere;
}

.row__title:hover {
    color: var(--color-link-hover);
    text-decoration: underline;
}

.row__host,
.row__date {
    font-size: 0.88rem;
    color: var(--color-muted);
}

.row__main .snippet {
    flex-basis: 100%;
}

.row__side {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: flex-end;
    gap: 0.3rem 0.75rem;
    max-width: 24rem;
}

.row__details {
    margin-left: 0;
    font-size: 0.88rem;
}

/* After the rows' own rules, so it wins (see .items--list). */
@container (max-width: 48rem) {
    .row {
        grid-template-columns: 1.5rem minmax(0, 1fr);
    }

    .row__side {
        grid-column: 2;
        justify-content: flex-start;
        max-width: none;
    }
}

.pagination {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: 1rem;
    margin: 2rem 0 0;
}

.pagination > :last-child {
    justify-self: end;
}

.pagination__where {
    color: var(--color-muted);
}

/* A link's own page. */
.link {
    max-width: 44rem;
    margin: 1rem auto 0;
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.link__picture {
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    overflow: hidden;
    background: var(--gruvbox-bg1);
}

.link__picture img {
    display: block;
    width: 100%;
    height: auto;
}

.link__title {
    font-family: var(--font-display);
    font-weight: normal;
    font-size: clamp(1.7rem, 5vw, 2.4rem);
    line-height: 1.15;
    color: var(--color-text-strong);
    margin: 0;
    overflow-wrap: anywhere;
    text-wrap: balance;
}

.link__title a {
    color: inherit;
    text-decoration-thickness: 1px;
    text-underline-offset: 0.12em;
}

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

.link__url,
.link__url-link {
    font-family: var(--font-ui);
    font-size: 0.92rem;
    color: var(--color-muted);
    overflow-wrap: anywhere;
    margin: 0;
}

.link__description {
    font-size: 1.15rem;
    margin: 0;
}

.link__subtitle {
    font-family: var(--font-ui);
    font-weight: normal;
    font-size: 0.85rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--color-muted);
    margin: 0 0 0.25rem;
}

.link__note {
    padding: 0.75rem 1rem;
    border-left: 3px solid var(--gruvbox-blue-faded);
    background: var(--color-surface);
    border-radius: 0 0.6rem 0.6rem 0;
}

.note {
    white-space: pre-wrap;
    margin: 0;
    overflow-wrap: anywhere;
}

.facts {
    display: grid;
    grid-template-columns: max-content minmax(0, 1fr);
    gap: 0.3rem 1rem;
    margin: 0.5rem 0;
    font-size: 0.95rem;
}

.facts dt {
    color: var(--color-muted);
}

.facts dd {
    margin: 0;
    overflow-wrap: anywhere;
}

.link__text summary {
    font-family: var(--font-ui);
    font-size: 0.95rem;
}

.pagetext {
    white-space: pre-line;
    max-height: 28rem;
    overflow-y: auto;
    padding: 0.75rem 1rem;
    font-size: 0.95rem;
    border: 1px solid var(--color-border);
    border-radius: 0.6rem;
    background: var(--color-surface);
    overflow-wrap: anywhere;
}

.inline-form {
    display: inline;
    margin: 0;
}

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

/* Tags page. */
.tags-page {
    max-width: 52rem;
    margin: 1rem auto 0;
}

.tag-rows {
    list-style: none;
    margin: 1rem 0 0;
    padding: 0;
    border-top: 1px solid var(--color-border);
}

.tag-row {
    display: grid;
    grid-template-columns: minmax(6rem, 1fr) 6rem minmax(0, 2fr) auto;
    gap: 0.5rem 1rem;
    align-items: center;
    padding: 0.5rem 0;
    border-bottom: 1px solid var(--color-border);
}

.tag-row__name {
    font-size: 1.05rem;
    overflow-wrap: anywhere;
}

.tag-row__count {
    color: var(--color-muted);
    font-size: 0.9rem;
}

.tag-row__rename {
    display: flex;
    gap: 0.4rem;
    margin: 0;
}

.tag-row__rename input {
    padding: 0.3rem 0.5rem;
}

.tag-row__delete summary {
    margin: 0;
    font-size: 0.95rem;
    color: var(--color-error);
}

.tag-row__delete[open] summary {
    margin-bottom: 0.4rem;
}

/* Settings. */
.bookmarklet {
    display: inline-block;
    padding: 0.45rem 1rem;
    border: 1px dashed var(--gruvbox-blue-faded);
    border-radius: var(--radius);
    color: var(--gruvbox-blue-faded);
    text-decoration: none;
    cursor: grab;
}

textarea.code,
input.code {
    font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
    font-size: 0.85rem;
    min-height: 0;
}

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

.check input {
    width: auto;
}

.form .button {
    align-self: flex-start;
    width: auto;
}

@media (max-width: 52rem) {
    .library {
        grid-template-columns: minmax(0, 1fr);
        gap: 1rem;
    }

    .tagbar {
        display: none;
    }

    .tagbar-mobile {
        display: block;
        padding: 0.25rem 0.75rem 0.75rem;
        border: 1px solid var(--color-border);
        border-radius: var(--radius);
        background: var(--color-surface);
    }

    .tagbar-mobile summary {
        font-family: var(--font-ui);
        margin: 0.5rem 0 0;
    }

    .tagbar-mobile[open] summary {
        margin-bottom: 0.6rem;
    }

    .tag-row {
        grid-template-columns: minmax(0, 1fr) auto;
    }

    .tag-row__rename {
        grid-column: 1 / -1;
    }
}

@media (max-width: 34rem) {
    .add__fields {
        grid-template-columns: minmax(0, 1fr);
    }

    .search {
        flex-wrap: wrap;
    }

    .search input[type="search"] {
        flex-basis: 100%;
    }

    .search select {
        flex: 1;
    }

    .view-switch__label {
        display: none;
    }

    .facts {
        grid-template-columns: minmax(0, 1fr);
    }

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

/* Comments (comments.rhys.wtf's thread, styled by static/comments.css):
   a section on a link's page, and the "💬 n" in lists. */
.link__comments {
    margin: 1.5rem 0 1rem;
}

.link__comments summary {
    font-family: var(--font-ui);
    font-size: 0.95rem;
}

.link__comments-body {
    padding-top: 0.75rem;
}

.link__comments-unavailable {
    margin: 0.5rem 0 0;
    color: var(--color-muted);
}

.comment-bubble {
    width: 1em;
    height: 1em;
    vertical-align: -0.15em;
    margin-right: 0.3em;
}

.comment-count {
    white-space: nowrap;
    color: var(--color-muted);
}

/* A link's actions on its card or row: Read, the archive's copy when the
   page has gone, "To read", Details. Above the card's own link. */
.card__details,
.row__details {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.2rem 0.75rem;
}

.to-read {
    font: inherit;
    color: var(--color-link);
    background: none;
    border: 0;
    padding: 0;
    cursor: pointer;
    text-decoration: underline;
    text-underline-offset: 0.12em;
}

.to-read--on {
    font-weight: bold;
}

.link__follow {
    font-family: var(--font-ui);
    margin: 1rem 0;
}

/* The reading view: the kept text in Recoleta at 18/28 on a 34em
   measure, black on the page's own ground, nothing moving: as Dailies'
   editions read, and as an e-ink screen wants. */
.reader {
    max-width: 34em;
    margin: 1.5rem auto 3rem;
    font-family: var(--font-body);
    font-size: 1.125rem;
    line-height: 1.556;
    color: var(--color-text-strong);
    overflow-wrap: break-word;
}

.reader__title {
    font-family: var(--font-display);
    font-weight: normal;
    font-size: 2rem;
    line-height: 1.2;
    margin: 0.3rem 0 0.5rem;
    text-wrap: balance;
}

.reader__byline {
    display: flex;
    flex-wrap: wrap;
    gap: 0.2rem 1rem;
    font-family: var(--font-ui);
    font-size: 0.95rem;
    margin: 0 0 2rem;
}

.reader__text p {
    margin: 0 0 1em;
    hyphens: auto;
}

.reader__none {
    font-style: italic;
}

.reader__foot {
    margin-top: 2.5rem;
    padding-top: 1rem;
    border-top: 1px solid var(--color-border);
}

.reader__url {
    display: none;
}

@media print {
    .site-header,
    .site-footer,
    .skip-link,
    .reader__foot {
        display: none;
    }

    .reader {
        margin: 0 auto;
        font-size: 11.5pt;
        color: #000;
    }

    .reader__url {
        display: block;
        font-family: var(--font-ui);
        font-size: 9pt;
        overflow-wrap: anywhere;
    }
}

/* An admin's read-only view of someone's links (admin_view.rs). */
.admin-banner {
    margin: 0 0 1rem;
    padding: .6rem 1rem;
    border: 2px solid var(--gruvbox-orange-faded);
    border-radius: 1rem;
    background: var(--color-surface);
    color: var(--color-text);
    font-family: var(--font-ui);
    font-weight: bold;
}
