/* ==========================================================================
   Hundehütte — design tokens
   Light palette on :root, dark palette via prefers-color-scheme unless the
   user picked a theme explicitly (data-theme on <html>, see theme_controller).
   ========================================================================== */
:root {
    color-scheme: light;

    --bg: #f2f3f6;
    --surface: #ffffff;
    --surface-2: #f6f7f9;
    --surface-sunken: #eceef2;
    --border: #e0e3e9;
    --border-strong: #cbd0d9;
    --text: #1a2030;
    --text-muted: #5d6779;
    --text-faint: #8b94a5;

    --accent: #c2410c;
    --accent-hover: #9a3412;
    --accent-contrast: #ffffff;
    --accent-soft: #fdeee4;
    --danger: #b42318;
    --danger-soft: #fdecea;
    --success: #067647;

    --box-slate: #64748b;
    --box-blue: #2563eb;
    --box-green: #16a34a;
    --box-amber: #d97706;
    --box-rose: #e11d48;
    --box-violet: #7c3aed;

    --shadow-sm: 0 1px 2px rgb(16 24 40 / 0.05);
    --shadow: 0 1px 3px rgb(16 24 40 / 0.08), 0 1px 2px rgb(16 24 40 / 0.04);
    --shadow-lg: 0 12px 32px rgb(16 24 40 / 0.16), 0 2px 6px rgb(16 24 40 / 0.06);

    /* the appearance settings set --radius, --transition, --page-transition (see Appearance.php) */
    --radius: 10px;
    --radius-sm: calc(var(--radius) * .6);
    --radius-lg: calc(var(--radius) * 1.4);
    --transition: 120ms;
    --page-transition: 250ms;
    --box-border-width: 1px;
    --box-border-color: var(--border);

    --font: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    --gutter: clamp(12px, 2.5vw, 24px);
}

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
        color-scheme: dark;
        --bg: #0e1117;
        --surface: #171b23;
        --surface-2: #1d222c;
        --surface-sunken: #12151c;
        --border: #272d39;
        --border-strong: #363e4d;
        --text: #e7eaf0;
        --text-muted: #a3acbc;
        --text-faint: #6e7889;
        --accent: #fb923c;
        --accent-hover: #fdba74;
        --accent-contrast: #1c1006;
        --accent-soft: #2a1c12;
        --danger: #f97066;
        --danger-soft: #2c1513;
        --success: #47cd89;
        --box-slate: #94a3b8;
        --box-blue: #60a5fa;
        --box-green: #4ade80;
        --box-amber: #fbbf24;
        --box-rose: #fb7185;
        --box-violet: #a78bfa;
        --shadow-sm: 0 1px 2px rgb(0 0 0 / 0.3);
        --shadow: 0 1px 3px rgb(0 0 0 / 0.4);
        --shadow-lg: 0 16px 40px rgb(0 0 0 / 0.55);
    }
}

:root[data-theme="dark"] {
    color-scheme: dark;
    --bg: #0e1117;
    --surface: #171b23;
    --surface-2: #1d222c;
    --surface-sunken: #12151c;
    --border: #272d39;
    --border-strong: #363e4d;
    --text: #e7eaf0;
    --text-muted: #a3acbc;
    --text-faint: #6e7889;
    --accent: #fb923c;
    --accent-hover: #fdba74;
    --accent-contrast: #1c1006;
    --accent-soft: #2a1c12;
    --danger: #f97066;
    --danger-soft: #2c1513;
    --success: #47cd89;
    --box-slate: #94a3b8;
    --box-blue: #60a5fa;
    --box-green: #4ade80;
    --box-amber: #fbbf24;
    --box-rose: #fb7185;
    --box-violet: #a78bfa;
    --shadow-sm: 0 1px 2px rgb(0 0 0 / 0.3);
    --shadow: 0 1px 3px rgb(0 0 0 / 0.4);
    --shadow-lg: 0 16px 40px rgb(0 0 0 / 0.55);
}

/* --------------------------------------------------------------------------
   Appearance (Appearance.php, appearance_controller.js): attributes on <html>
   data-shadow, data-border, and data-accent with --accent-base, from which the
   other accent shades are derived per light/dark mode.
   -------------------------------------------------------------------------- */
:root[data-shadow="none"] { --shadow-sm: none; --shadow: none; }
:root[data-shadow="strong"] {
    --shadow-sm: 0 2px 6px rgb(16 24 40 / 0.10), 0 1px 2px rgb(16 24 40 / 0.06);
    --shadow: 0 8px 22px rgb(16 24 40 / 0.14), 0 2px 5px rgb(16 24 40 / 0.06);
}
:root[data-border="none"] { --box-border-width: 0px; }
:root[data-border="strong"] { --box-border-width: 2px; --box-border-color: var(--border-strong); }
:root[data-accent] {
    --accent: var(--accent-base);
    --accent-hover: color-mix(in oklab, var(--accent-base) 82%, black);
    --accent-contrast: var(--accent-contrast-base);
    --accent-soft: color-mix(in oklab, var(--accent-base) 13%, white);
}

@media (prefers-color-scheme: dark) {
    :root[data-shadow="strong"]:not([data-theme="light"]) {
        --shadow-sm: 0 2px 8px rgb(0 0 0 / 0.5);
        --shadow: 0 10px 26px rgb(0 0 0 / 0.6);
    }
    :root[data-accent]:not([data-theme="light"]) {
        --accent: color-mix(in oklab, var(--accent-base) 70%, white);
        --accent-hover: color-mix(in oklab, var(--accent-base) 50%, white);
        --accent-contrast: #111111;
        --accent-soft: color-mix(in oklab, var(--accent-base) 20%, #0e1117);
    }
}
:root[data-shadow="strong"][data-theme="dark"] {
    --shadow-sm: 0 2px 8px rgb(0 0 0 / 0.5);
    --shadow: 0 10px 26px rgb(0 0 0 / 0.6);
}
:root[data-accent][data-theme="dark"] {
    --accent: color-mix(in oklab, var(--accent-base) 70%, white);
    --accent-hover: color-mix(in oklab, var(--accent-base) 50%, white);
    --accent-contrast: #111111;
    --accent-soft: color-mix(in oklab, var(--accent-base) 20%, #0e1117);
}

/* Preferences, "respect reduce motion" (<body data-reduced-motion>): only then does the OS setting
   turn off the durations of the look; otherwise they are an explicit choice and 0 is off. */
@media (prefers-reduced-motion: reduce) {
    body[data-reduced-motion] { --transition: 0ms; --page-transition: 0ms; }
}

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

/* the scrollbar always shows, so the layout does not jump sideways between short and long pages
   or when a box grows past the window */
html { -webkit-text-size-adjust: 100%; overflow-y: scroll; }

body {
    margin: 0;
    min-height: 100vh;
    background: var(--bg);
    color: var(--text);
    font: 14px/1.45 var(--font);
    -webkit-font-smoothing: antialiased;
}

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

h1, h2, h3 { margin: 0; line-height: 1.2; }

img { max-width: 100%; }

[hidden] { display: none !important; }

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

.icon {
    width: 1.15em;
    height: 1.15em;
    flex: none;
    vertical-align: -0.2em;
}

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

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

/* ==========================================================================
   Buttons
   ========================================================================== */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    height: 34px;
    padding: 0 14px;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
    background: var(--surface);
    color: var(--text);
    font: 500 13.5px/1 var(--font);
    cursor: pointer;
    white-space: nowrap;
    transition: background-color var(--transition), border-color var(--transition), color var(--transition);
}
.btn:hover { background: var(--surface-2); text-decoration: none; }
.btn:disabled { opacity: .55; cursor: default; }

.btn--primary {
    background: var(--accent);
    border-color: var(--accent);
    color: var(--accent-contrast);
}
.btn--primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); }

.btn--danger { color: var(--danger); }
.btn--danger:hover { background: var(--danger-soft); border-color: var(--danger); }

.btn--block { width: 100%; height: 40px; }

.btn--ghost {
    border-color: transparent;
    background: transparent;
    color: var(--text-muted);
}
.btn--ghost:hover { background: var(--surface-2); color: var(--text); }

.icon-btn {
    display: inline-grid;
    place-items: center;
    width: 30px;
    height: 30px;
    padding: 0;
    border: 0;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--text-muted);
    cursor: pointer;
}
.icon-btn:hover { background: var(--surface-sunken); color: var(--text); }

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

/* ==========================================================================
   Forms
   ========================================================================== */
.field { display: grid; align-content: start; gap: 6px; margin-bottom: 14px; }

.field > label, .field legend, .label {
    font-weight: 600;
    font-size: 13px;
    color: var(--text);
}

.input, .field input:not([type="checkbox"], [type="radio"], [type="hidden"]), .field select, .field textarea {
    width: 100%;
    height: 38px;
    padding: 0 11px;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
    background: var(--surface);
    color: var(--text);
    font: 14px var(--font);
}
.field textarea { height: auto; min-height: 80px; padding: 8px 11px; }
.field textarea.textarea--code { font: 12.5px/1.6 ui-monospace, SFMono-Regular, Menlo, monospace; white-space: pre; overflow-x: auto; }
.input:focus, .field input:focus, .field select:focus, .field textarea:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-soft);
}

/* box | label; help and errors under the label, also when a long label wraps */
.field--checkbox { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; gap: 4px 8px; }
.field--checkbox > :not(input, label) { grid-column: 2; }
.field--checkbox label { font-weight: 500; }

.help { font-size: 12.5px; color: var(--text-muted); }
.field .help { margin: 0; }

.field-errors, .form-errors {
    margin: 0;
    padding: 0;
    list-style: none;
    color: var(--danger);
    font-size: 13px;
}
.field--error input, .field--error select { border-color: var(--danger); }

.choice-row { display: flex; flex-wrap: wrap; gap: 8px; }

.form-actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 8px;
    margin-top: 6px;
}

/* Segmented control for small radio groups (columns, item counts) */
.segmented {
    display: inline-flex;
    flex-wrap: wrap;
    gap: 2px;
    width: fit-content;
    padding: 3px;
    border-radius: 8px;
    background: var(--surface-sunken);
}
.segmented__option { position: relative; }
.segmented__option input { position: absolute; opacity: 0; pointer-events: none; }
.segmented__option span {
    display: block;
    min-width: 40px;
    padding: 5px 12px;
    border-radius: 6px;
    color: var(--text-muted);
    font-weight: 500;
    text-align: center;
    cursor: pointer;
}
.segmented__option span:hover { color: var(--text); }
.segmented__option input:checked + span { background: var(--surface); color: var(--text); box-shadow: var(--shadow); }
.segmented__option input:focus-visible + span { outline: 2px solid var(--accent); outline-offset: 1px; }

.danger-zone {
    display: flex;
    justify-content: flex-start;
    margin-top: 18px;
    padding-top: 14px;
    border-top: 1px solid var(--border);
}

/* box settings: "apply to other boxes", between the save buttons and the danger zone */
.apply-layout {
    margin-top: 18px;
    padding-top: 14px;
    border-top: 1px solid var(--border);
}
.apply-layout .field { margin-bottom: 10px; }
.apply-layout__actions { display: flex; flex-wrap: wrap; gap: 8px; }

.checkbox-list { display: flex; flex-wrap: wrap; gap: 6px 16px; }
.checkbox-list__option { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; cursor: pointer; }

/* ==========================================================================
   Alerts & flashes
   ========================================================================== */
.alert {
    margin-bottom: 14px;
    padding: 10px 12px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface-2);
}
.alert--error { border-color: var(--danger); background: var(--danger-soft); color: var(--danger); }
.alert--success { border-color: var(--success); color: var(--success); }

/* ==========================================================================
   Auth pages (login, register, reset password)
   ========================================================================== */
.auth {
    display: grid;
    place-items: center;
    align-content: center;
    gap: 14px;
    min-height: 100vh;
    padding: 32px 16px;
}
.auth__card {
    width: 100%;
    max-width: 380px;
    padding: 28px;
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    background: var(--surface);
    box-shadow: var(--shadow);
}
.auth__brand {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 20px;
    color: var(--text);
    font-weight: 700;
    font-size: 17px;
}
.auth__brand .icon { color: var(--accent); width: 26px; height: 26px; }
.auth__title { margin-bottom: 6px; font-size: 20px; }
.auth__lead { margin: 0 0 18px; color: var(--text-muted); }
.auth__footer { margin-top: 18px; text-align: center; color: var(--text-muted); }
.auth__legal { display: flex; gap: 18px; font-size: 13px; }
.auth__legal a { color: var(--text-muted); }
.auth__row { display: flex; justify-content: space-between; align-items: center; margin: -4px 0 14px; font-size: 13px; }

/* Bragging numbers under the login form (SiteSettings::$loginStats), animated by stats_controller.js */
.login-stats { position: relative; width: 100%; max-width: 560px; text-align: center; }
.login-stats__value { display: inline-block; } /* so the pop can scale it */
.login-stats__doge {
    position: absolute;
    z-index: 1;
    font-family: "Comic Sans MS", "Comic Neue", "Chalkboard SE", cursive;
    font-size: 17px;
    font-weight: 700;
    white-space: nowrap;
    text-shadow: 0 1px 2px rgb(0 0 0 / .15);
    pointer-events: none;
}
.login-stats__title { margin: 6px 0 12px; color: var(--text-muted); font-size: 13px; font-weight: 600; letter-spacing: .02em; }
.login-stats__grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 10px;
    margin: 0;
    padding: 0;
    list-style: none;
}
.login-stats__item {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 14px 10px;
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    background: var(--surface);
}
.login-stats__value {
    color: var(--accent);
    font-size: 26px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    line-height: 1.1;
}
.login-stats__label { color: var(--text-muted); font-size: 12px; line-height: 1.35; }
.login-stats__footnote { margin: 10px 0 0; color: var(--text-muted); font-size: 11px; font-style: italic; }
@media (max-width: 560px) {
    .login-stats__grid { grid-template-columns: repeat(2, 1fr); }
}

/* ==========================================================================
   App shell: top bar
   ========================================================================== */
.topbar {
    position: sticky;
    top: 0;
    z-index: 20;
    display: flex;
    align-items: center;
    gap: 12px;
    height: 56px;
    padding: 0 var(--gutter);
    border-bottom: 1px solid var(--border);
    background: color-mix(in srgb, var(--surface) 88%, transparent);
    backdrop-filter: saturate(1.4) blur(10px);
}
.brand {
    display: flex;
    align-items: center;
    gap: 8px;
    color: var(--text);
    font-weight: 700;
    font-size: 16px;
    letter-spacing: -0.01em;
}
.brand:hover { text-decoration: none; }
.brand .icon { width: 24px; height: 24px; color: var(--accent); }

.topbar__actions { display: flex; align-items: center; gap: 6px; margin-left: auto; }

@media (max-width: 560px) {
    .brand span { display: none; }
    .btn__label { display: none; }
}

/* Dropdown menu built on <details> */
.menu { position: relative; }
.menu > summary { list-style: none; }
.menu > summary::-webkit-details-marker { display: none; }
.menu__panel {
    position: absolute;
    right: 0;
    top: calc(100% + 6px);
    z-index: 30;
    min-width: 220px;
    padding: 6px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
    box-shadow: var(--shadow-lg);
}
.menu__header { padding: 8px 10px; color: var(--text-muted); font-size: 12.5px; overflow: hidden; text-overflow: ellipsis; }
.menu__item {
    display: flex;
    align-items: center;
    gap: 9px;
    width: 100%;
    padding: 8px 10px;
    border: 0;
    border-radius: var(--radius-sm);
    background: none;
    color: var(--text);
    font: 13.5px var(--font);
    text-align: left;
    cursor: pointer;
}
.menu__item:hover { background: var(--surface-2); text-decoration: none; }
.menu__item--danger { color: var(--danger); }
.menu__item--quiet { color: var(--text-muted); font-size: 13px; }
.menu__item[aria-current="true"] { color: var(--accent); font-weight: 600; }
.menu__sep { height: 1px; margin: 6px 4px; background: var(--border); }

.avatar {
    display: grid;
    place-items: center;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: var(--accent-soft);
    color: var(--accent);
    font-weight: 700;
    text-transform: uppercase;
    cursor: pointer;
}

/* Topbar split buttons (dashboard/_bulk_action.html.twig): action on this tab + dropdown "on all tabs" */
.bulk-actions { display: flex; gap: 6px; }
.split { display: flex; }
.split .inline-form { display: flex; }
.split__main { padding: 0 9px; border-top-right-radius: 0; border-bottom-right-radius: 0; }
.split__toggle { padding: 0 4px; margin-left: -1px; border-top-left-radius: 0; border-bottom-left-radius: 0; }
.split__toggle .icon { width: 14px; height: 14px; }
.split .menu__panel { min-width: 240px; }

/* ==========================================================================
   Tab bar (in the top bar between brand and actions)
   ========================================================================== */
.tabbar {
    display: flex;
    flex: 1 1 auto;
    align-items: center;
    gap: 4px;
    min-width: 0;
}
/* scrolls sideways without a scrollbar: the arrows (tabscroll_controller.js), touch or the wheel move it */
.tabbar__viewport {
    position: relative; /* the offsetParent of the tabs (tabscroll_controller.js) */
    flex: 0 1 auto;
    min-width: 0;
    /* vertical room so the overflow clip doesn't cut the focus outline */
    padding: 4px 2px;
    overflow-x: auto;
    scrollbar-width: none;
}
.tabbar__viewport::-webkit-scrollbar { display: none; }
.tabbar__list { display: flex; gap: 4px; }
.tabbar__arrow { flex: none; }
.tabbar__arrow:disabled { opacity: .35; cursor: default; }
.tabbar__arrow:disabled:hover { background: transparent; color: var(--text-muted); }
.tab {
    display: flex;
    align-items: center;
    border-radius: var(--radius-sm);
    transition: background-color var(--transition), color var(--transition);
}
.tab:hover { background: var(--surface-2); }
.tab__link {
    display: flex;
    align-items: center;
    height: 34px;
    padding: 0 14px;
    border-radius: var(--radius-sm);
    color: var(--text-muted);
    font-weight: 500;
    white-space: nowrap;
    transition: color var(--transition);
}
.tab__link:hover { color: var(--text); text-decoration: none; }
/* No outer shadow: overflow-x on .tabbar clips vertically too, and a strong shadow never fits the
   top bar. A neutral sunken background plus a ring following the box border setting mark the
   current tab. */
.tab--current, .tab--current:hover {
    background: var(--surface-sunken);
    box-shadow: inset 0 0 0 var(--box-border-width) var(--box-border-color);
}
.tab--current .tab__link, .tab--current .tab__link:hover { color: var(--text); font-weight: 600; }
/* room for the settings button, which only shows while editing (mode_controller.js) */
[data-mode="edit"] .tab--current .tab__link { padding-right: 4px; }
.tab--current .icon-btn { width: 26px; height: 26px; margin-right: 4px; }
.tab--current .icon-btn:hover { background: var(--border); } /* the tab itself is already sunken */
.tabbar__add { flex: none; }
.sortable-ghost.tab { opacity: .4; }

/* Phones and narrow windows: the tabs get a row of their own below brand and actions. Squeezed in
   between, the actions (about 400px) left them no room at all, and only their arrows showed, over
   the buttons. Above 900px, at least two or three tabs fit next to them. */
@media (max-width: 900px) {
    .topbar { flex-wrap: wrap; row-gap: 2px; height: auto; min-height: 56px; padding-top: 8px; padding-bottom: 2px; }
    .tabbar { order: 1; flex-basis: 100%; }
}
/* the smallest phones (360px): brand and actions still on one row */
@media (max-width: 400px) {
    .topbar { column-gap: 8px; }
    .topbar__actions, .bulk-actions { gap: 4px; }
    .split__main { padding: 0 6px; }
}

/* ==========================================================================
   Dashboard columns & boxes
   ========================================================================== */
.dashboard {
    display: grid;
    grid-template-columns: repeat(var(--columns, 3), minmax(0, 1fr));
    gap: 16px;
    align-items: start;
    padding: 16px var(--gutter) 48px;
}
.column {
    display: flex;
    flex-direction: column;
    gap: 16px;
    min-height: 120px;
    border-radius: var(--radius);
}
.column.is-drag-target { outline: 2px dashed var(--border-strong); outline-offset: 4px; }

/* a tab with wide boxes: placed by box_layout_controller.js */
.dashboard--packed { position: relative; }
.dashboard--packed .box:not(.sortable-fallback) { position: absolute; }
.dashboard--packed.is-placed .box:not(.sortable-fallback) { transition: top var(--transition) ease, left var(--transition) ease; }

@media (max-width: 800px) {
    .dashboard { grid-template-columns: minmax(0, 1fr); }
    .column { min-height: 0; }
}

.box {
    --box-color: var(--box-slate);
    position: relative;
    border: var(--box-border-width) solid var(--box-border-color);
    border-top: 3px solid var(--box-color);
    border-radius: var(--radius);
    background: var(--surface);
    box-shadow: var(--shadow-sm);
}
.box--slate { --box-color: var(--box-slate); }
.box--blue { --box-color: var(--box-blue); }
.box--green { --box-color: var(--box-green); }
.box--amber { --box-color: var(--box-amber); }
.box--rose { --box-color: var(--box-rose); }
.box--violet { --box-color: var(--box-violet); }
/* new headlines (app.js, glow()): an overlay in the box colour over the box, its title bar or a
   headline; only its opacity is animated */
.is-flashing::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background: var(--box-color);
    opacity: 0;
    pointer-events: none;
    will-change: opacity;
}
/* inside the box's rounded corners (below its 3px top border) */
.box__header.is-flashing::after { border-radius: max(0px, var(--radius) - 3px) max(0px, var(--radius) - 3px) 0 0; }

.box__header {
    position: relative;
    display: flex;
    align-items: center;
    gap: 8px;
    min-height: 42px;
    padding: 4px 6px 4px 12px;
    cursor: grab;
    user-select: none;
}
.box__header:active { cursor: grabbing; }
/* reading is the default (mode_controller.js): no editing tools, nothing to drag until the pencil */
:root:not([data-mode="edit"]) .edit-only { display: none !important; }
:root:not([data-mode="edit"]) .box__header { cursor: default; }
.mode-toggle[aria-pressed="true"] { border-color: var(--accent); color: var(--accent); }
.box__icon {
    position: relative;
    display: grid;
    place-items: center;
    width: 20px;
    height: 20px;
    flex: none;
    color: var(--box-color);
}
.box__icon img {
    position: absolute;
    inset: 2px;
    width: 16px;
    height: 16px;
    border-radius: 3px;
    background: var(--surface);
}
.box__title {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    font-size: 14px;
    font-weight: 650;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.box__title a { color: inherit; }
/* the title toggles the box, and still drags it (a drop swallows the click: sortable_controller) */
.box__toggle {
    display: block;
    width: 100%;
    padding: 0;
    overflow: hidden;
    border: 0;
    background: none;
    color: inherit;
    font: inherit;
    text-align: start;
    text-overflow: ellipsis;
    white-space: nowrap;
    cursor: pointer;
}
.box__count {
    padding: 0 7px;
    margin-left: 0.333rem;
    border-radius: 999px;
    background: color-mix(in srgb, var(--box-color) 16%, transparent);
    color: var(--box-color);
    font-size: 11.5px;
    font-weight: 700;
    line-height: 19px;
}
.box__actions { display: flex; gap: 0; opacity: 0; transition: opacity var(--transition); }
.box:hover .box__actions, .box:focus-within .box__actions { opacity: 1; }
@media (hover: none) { .box__actions { opacity: 1; } }
.box__actions .icon-btn { width: 28px; height: 28px; }
/* the grip drags the box in reading mode too (sortable_controller.js); shown with the other tools */
.box__handle { cursor: grab; touch-action: none; }
.is-sorting .box__handle { cursor: grabbing; }

.box__body { border-top: 1px solid var(--border); }
.box--collapsed .box__body { display: none; }
.box--collapsed .collapse-icon { transform: rotate(-90deg); }
.collapse-icon { transition: transform var(--transition); }

/* Zoom (box_zoom_controller.js): the frame is pinned over the box's column(s) from below the top bar
   to the bottom of the window; the <article> stays behind as a placeholder of its former height. */
.box--zoomed { border-style: dashed; border-color: var(--border-strong); background: transparent; box-shadow: none; }
.box--zoomed > turbo-frame {
    position: fixed;
    z-index: 15; /* below the top bar */
    top: var(--zoom-top);
    bottom: 16px;
    left: var(--zoom-left);
    width: var(--zoom-width);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    border: var(--box-border-width) solid var(--box-border-color);
    border-top: 3px solid var(--box-color);
    border-radius: var(--radius);
    background: var(--surface);
    box-shadow: var(--shadow-lg);
}
.box--zoomed .box__header { cursor: default; } /* not dragged while zoomed (sortable filter) */
.box--zoomed .box__actions { opacity: 1; }
.box--zoomed .box__handle { display: none; }
/* also a collapsed box: zooming shows its content, shrinking back collapses it again */
.box--zoomed .box__body { display: block; flex: 1; min-height: 0; overflow: hidden auto; }
/* a feed box fills the height with lines (pager_controller.js), its footer at the bottom */
.box--zoomed .pager { display: flex; flex-direction: column; min-height: 100%; }
.box--zoomed .pager > .box__footer { margin-top: auto; }
.box__zoom:not([aria-pressed="true"]) .unzoom-icon, .box__zoom[aria-pressed="true"] .zoom-icon { display: none; }

.sortable-ghost.box { opacity: .35; }
.sortable-chosen.box { box-shadow: var(--shadow-lg); }

.box__footer {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 8px;
    padding: 6px 12px;
    border-top: 1px solid var(--border);
    color: var(--text-faint);
    font-size: 12px;
}
.box__footer form { margin: 0; }
.box__footer-actions { display: inline-flex; align-items: center; gap: 12px; margin-left: auto; white-space: nowrap; }
.box__footer-error { display: inline-flex; align-items: center; gap: 4px; color: var(--danger); }
.link-btn {
    padding: 0;
    border: 0;
    background: none;
    color: var(--text-muted);
    font: inherit;
    cursor: pointer;
}
.link-btn:hover { color: var(--accent); text-decoration: underline; }

/* Loading skeleton & states inside a box */
.skeleton { padding: 10px 12px; }
.skeleton__line {
    height: 10px;
    margin: 8px 0;
    border-radius: 4px;
    background: linear-gradient(90deg, var(--surface-sunken) 0%, var(--surface-2) 50%, var(--surface-sunken) 100%);
    background-size: 200% 100%;
    animation: shimmer 1.4s infinite linear;
}
.skeleton__line:nth-child(2n) { width: 82%; }
.skeleton__line:nth-child(3n) { width: 64%; }
@keyframes shimmer { from { background-position: 200% 0; } to { background-position: -200% 0; } }
@media (prefers-reduced-motion: reduce) { .skeleton__line { animation: none; } }

.box-state {
    display: flex;
    gap: 8px;
    align-items: flex-start;
    padding: 14px 12px;
    color: var(--text-muted);
    font-size: 13px;
}
.box-state--error { color: var(--danger); }
.box-state .icon { margin-top: 1px; }
.box__body > .box-state + .box-state, .skeleton + .box-state { padding-top: 0; }

/* ==========================================================================
   Feed items
   ========================================================================== */
.items {
    /* density (FeedSettingsType::DENSITIES): "normal" here; narrower letters need a font with a width axis */
    --item-size: 14px;
    --item-pad: 5px;
    --item-stretch: normal;
    --item-tracking: normal;
    --item-time-size: 12px;
    --item-excerpt-size: 12.5px;
    margin: 0;
    padding: 0;
    list-style: none;
}
.items[data-density="tight"] { --item-size: 12.5px; --item-pad: 1px; --item-stretch: 80%; --item-tracking: -0.01em; --item-time-size: 11px; --item-excerpt-size: 11.5px; }
.items[data-density="compact"] { --item-size: 13px; --item-pad: 3px; --item-stretch: 90%; --item-tracking: -0.005em; --item-time-size: 11.5px; --item-excerpt-size: 12px; }
.items[data-density="relaxed"] { --item-size: 14.5px; --item-pad: 7px; --item-excerpt-size: 13px; }
.items[data-density="large"] { --item-size: 16px; --item-pad: 8px; --item-time-size: 13px; --item-excerpt-size: 14px; }

/* Paging (pager_controller.js): the viewport shows "lines" items, the list slides by whole pages */
.pager__viewport { box-sizing: content-box; padding: 4px 0; overflow: hidden; touch-action: pan-y; }
/* the OS setting "reduce motion" only counts when the user chose so (body[data-reduced-motion] above) */
.pager__viewport .items { transition: transform var(--page-transition) ease; }
.pager__controls { display: inline-flex; align-items: center; gap: 2px; margin: -4px 0; }
.pager__controls[hidden] { display: none; }
.pager__controls .icon-btn { width: 24px; height: 24px; }
.pager__controls .icon-btn:disabled { opacity: .35; cursor: default; }
.pager__status { min-width: 3.2em; color: var(--text-faint); font-size: 12px; text-align: center; font-variant-numeric: tabular-nums; }
.item {
    position: relative;
    font-size: var(--item-size);
    font-stretch: var(--item-stretch);
    letter-spacing: var(--item-tracking);
}
.item__link {
    display: flex;
    align-items: baseline;
    gap: 8px;
    padding: var(--item-pad) 12px var(--item-pad) 22px;
    color: var(--text);
}
.item__link:hover { background: var(--surface-2); text-decoration: none; }
.item__link:hover .item__title { text-decoration: underline; }
.item__title {
	flex: 1;
	min-width: 0;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}
.item__time { flex: none; color: var(--text-faint); font-size: var(--item-time-size); white-space: nowrap; }
.item--unread .item__title { font-weight: 600; }
.item--unread::before {
    content: "";
    position: absolute;
    left: 10px;
    top: calc(var(--item-pad) + 0.5lh - 3px); /* centred on the first line */
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--box-color, var(--accent));
}
.item--read .item__title { color: var(--text-muted); }
.item__excerpt {
    margin: -2px 12px calc(var(--item-pad) + 1px) 22px;
    color: var(--text-muted);
    font-size: var(--item-excerpt-size);
    display: -webkit-box;
    height: 2lh; /* also when empty: all items equally tall, see pager_controller.js */
    line-clamp: 2;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* ==========================================================================
   Bookmarks
   ========================================================================== */
/* minmax(0, 1fr): an auto column grows to the full length of the longest title (nowrap) and pushes
   past the box, in narrow columns even past the window */
.bookmarks { margin: 0; padding: 6px; list-style: none; display: grid; grid-template-columns: minmax(0, 1fr); gap: 2px; }
.bookmark { display: flex; align-items: center; gap: 4px; border-radius: var(--radius-sm); }
/* an empty box keeps its list as a drop zone for links from other boxes; the hint goes once a link is in */
[data-sortable-group-value="bookmarks"]:has(.bookmark) > .bookmarks-empty { display: none; }
[data-sortable-group-value="bookmarks"]:not(:has(.bookmark)) > .bookmarks { min-height: 32px; padding-top: 0; }
.bookmark:hover { background: var(--surface-2); }
.bookmark__link {
    display: flex;
    flex: 1;
    min-width: 0;
    align-items: center;
    gap: 10px;
    padding: 6px;
    color: var(--text);
}
.bookmark__link:hover { text-decoration: none; }
.bookmark__title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bookmark__host { margin-left: auto; color: var(--text-faint); font-size: 12px; white-space: nowrap; }
.bookmark__tools { display: flex; opacity: 0; }
.bookmark:hover .bookmark__tools, .bookmark:focus-within .bookmark__tools { opacity: 1; }
@media (hover: none) { .bookmark__tools { opacity: 1; } }
.bookmark__tools .icon-btn { width: 26px; height: 26px; }
.bookmark__tools form { display: contents; }
.icon-btn--danger:hover { background: var(--danger-soft); color: var(--danger); }
/* only the grip at the end of the row drags (sortable_controller.js), shown on hover like the tools */
.bookmark__handle { width: 26px; height: 26px; cursor: grab; touch-action: none; opacity: 0; }
/* time left of a temporary link: a ring that empties, details in a tooltip; a click keeps the link (_expiry.html.twig) */
.expiry-form { display: contents; }
.expiry { display: inline-grid; flex: none; place-items: center; width: 22px; height: 22px; padding: 0; border: 0; border-radius: 50%; background: none; color: inherit; cursor: pointer; }
.expiry:hover, .expiry--badge:hover { background: var(--surface-sunken); } /* the row itself turns surface-2 */
.expiry svg { width: 16px; height: 16px; }
.expiry__track { fill: none; stroke: var(--border-strong); stroke-width: 3; }
.expiry__fill { fill: none; stroke: var(--box-color, var(--accent)); stroke-width: 3; stroke-linecap: round; }
.expiry--low .expiry__fill { stroke: var(--danger); }
.expiry:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.expiry--badge { position: absolute; right: -2px; bottom: -2px; width: 18px; height: 18px; background: var(--surface); box-shadow: 0 0 0 1px var(--border); }
.expiry--badge svg { width: 14px; height: 14px; }
.tooltip {
    position: fixed;
    z-index: 1000;
    max-width: 280px;
    padding: 7px 10px;
    border-radius: var(--radius-sm);
    background: var(--text);
    color: var(--surface);
    font-size: 12.5px;
    line-height: 1.45;
    white-space: pre-line;
    box-shadow: var(--shadow-lg);
    pointer-events: none;
}
.tooltip::after {
    content: '';
    position: absolute;
    left: calc(var(--arrow-x, 50%) - 5px);
    border: 5px solid transparent;
}
.tooltip[data-placement="above"]::after { top: 100%; border-top-color: var(--text); }
.tooltip[data-placement="below"]::after { bottom: 100%; border-bottom-color: var(--text); }
.bookmark:hover .bookmark__handle, .bookmark:focus-within .bookmark__handle { opacity: 1; }
@media (hover: none) { .bookmark__handle { opacity: 1; } }
.is-sorting .bookmark, .is-sorting .bookmark__link, .is-sorting .bookmark__handle { cursor: grabbing; }
.sortable-ghost.bookmark { opacity: .4; }
/* a link that was about to be added again lights up in the box colour, with a note that fades */
.bookmark--duplicate { animation: bookmark-duplicate 2.4s ease-out; }
.bookmark__note { margin-left: auto; color: var(--box-color); font-size: 12px; font-weight: 600; white-space: nowrap; animation: bookmark-note 4s ease-in forwards; }
@keyframes bookmark-duplicate {
    0%, 30% { background: color-mix(in srgb, var(--box-color) 28%, transparent); }
    100% { background: transparent; }
}
@keyframes bookmark-note {
    0%, 75% { opacity: 1; }
    100% { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
    .bookmark--duplicate { animation: none; background: color-mix(in srgb, var(--box-color) 20%, transparent); }
    .bookmark__note { animation: none; }
}
/* Shortcuts box: links as icon buttons; the title bar only while editing (moving, settings) */
:root:not([data-mode="edit"]) .box--type-shortcuts .box__header { display: none; }
.box--type-shortcuts.box--collapsed .box__body { display: block; }
.shortcuts { grid-template-columns: repeat(auto-fill, minmax(44px, 1fr)); gap: 4px; padding: 8px; }
.shortcut { position: relative; justify-content: center; }
.shortcut__link { display: grid; place-items: center; width: 44px; height: 44px; border-radius: var(--radius-sm); }
.shortcut__link:hover, .shortcut__link:focus-visible { background: var(--surface-2); text-decoration: none; }
.favicon--large { width: 32px; height: 32px; border-radius: 8px; font-size: 15px; }
.favicon--large img { inset: 4px; width: 24px; height: 24px; }
.shortcut__edit {
    position: absolute;
    top: -2px;
    right: -2px;
    display: grid;
    place-items: center;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: var(--surface);
    box-shadow: 0 0 0 1px var(--border-strong);
    color: var(--text-muted);
    opacity: 0;
}
.shortcut__edit .icon { width: 11px; height: 11px; }
.shortcut:hover .shortcut__edit, .shortcut:focus-within .shortcut__edit { opacity: 1; }
@media (hover: none) { .shortcut__edit { opacity: 1; } }
.box--type-shortcuts .box__footer { padding-top: 0; }

/* The dock: the user's shortcuts in a panel from the left (dashboard/index.html.twig, dock_controller.js) */
.dock {
    position: fixed;
    inset: 0 auto 0 0;
    width: min(320px, 100vw - 48px);
    height: 100vh;
    max-height: none;
    margin: 0;
    padding: 0;
    border: 0;
    border-right: 1px solid var(--border);
    background: var(--surface);
    color: var(--text);
    box-shadow: var(--shadow-lg);
    overflow-y: auto;
    --box-color: var(--accent);
    transition: translate var(--transition), display var(--transition) allow-discrete, overlay var(--transition) allow-discrete;
    translate: -100% 0;
}
.dock:popover-open { translate: 0 0; }
@starting-style { .dock:popover-open { translate: -100% 0; } }
.dock__bar {
    display: flex;
    align-items: center;
    gap: 8px;
    height: 56px;
    padding: 0 8px 0 16px;
    border-bottom: 1px solid var(--border);
}
.dock__title { flex: 1; font-size: 15px; }
/* the frame is the shortcuts box's (show.html.twig): its title bar and settings belong to no box here */
.dock .box__header { display: none; }
.dock .shortcuts { padding: 12px; }
.dock.is-drop-target { outline: 2px dashed var(--accent); outline-offset: -4px; }
.dock-toggle { margin-left: -6px; }

/*
 * The trash while a box or a link is dragged (trash_controller.js). A popover, to be above the open
 * dock; 40px above the bottom edge, clear of the strip where SortableJS scrolls the page.
 */
.trash {
    position: fixed;
    inset: auto 0 calc(40px + env(safe-area-inset-bottom));
    width: fit-content;
    height: auto;
    margin: 0 auto;
    padding: 14px 28px;
    align-items: center;
    gap: 10px;
    border: 2px dashed var(--danger);
    border-radius: 999px;
    background: var(--surface);
    color: var(--danger);
    box-shadow: var(--shadow-lg);
    font-weight: 600;
    white-space: nowrap;
    overflow: visible;
    transition: translate var(--transition), opacity var(--transition), scale var(--transition),
        background-color var(--transition), color var(--transition),
        display var(--transition) allow-discrete, overlay var(--transition) allow-discrete;
    translate: 0 16px;
    opacity: 0;
}
.trash:popover-open { display: flex; translate: 0 0; opacity: 1; }
@starting-style { .trash:popover-open { translate: 0 16px; opacity: 0; } }
.trash__drop { display: contents; }
.trash__drop .icon { width: 20px; height: 20px; }
.trash.is-active { border-style: solid; background: var(--danger); color: var(--surface); scale: 1.06; }
.trash__release, .trash.is-active .trash__hint { display: none; }
.trash.is-active .trash__release { display: inline; }
/* dropped on it: "Cancel" and "Delete" instead */
.trash__choice, .trash.is-asking .trash__drop { display: none; }
.trash.is-asking .trash__choice { display: contents; }
.trash.is-asking { padding: 8px; border-style: solid; }
/* the place the item would go back to if the delete is cancelled, and the item waiting for the answer */
.sortable-ghost.is-over-trash { opacity: .15; }
.is-trash-pending { opacity: .4; }

/* a link dragged over a bookmark box (bookmark_drop_controller.js), and while its title is looked up */
.box.is-drop-target { outline: 2px dashed var(--box-color); outline-offset: 2px; }
.box.is-adding { cursor: progress; }
.box.is-adding .bookmarks, .box.is-adding .box-state { opacity: .6; }

.favicon {
    position: relative;
    display: grid;
    place-items: center;
    width: 22px;
    height: 22px;
    flex: none;
    border-radius: 5px;
    background: var(--surface-sunken);
    color: var(--text-muted);
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    overflow: hidden;
}
.favicon img { position: absolute; inset: 3px; width: 16px; height: 16px; }

/* ==========================================================================
   Modal dialog (content is loaded into <turbo-frame id="modal">)
   ========================================================================== */
.modal {
    width: min(520px, calc(100vw - 32px));
    max-height: calc(100vh - 64px);
    padding: 0;
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    background: var(--surface);
    color: var(--text);
    box-shadow: var(--shadow-lg);
}
.modal::backdrop { background: rgb(10 14 22 / 0.45); backdrop-filter: blur(2px); }
.modal__header {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 16px 16px 0 20px;
}
.modal__title { flex: 1; font-size: 17px; }
.modal__body { padding: 16px 20px 20px; }
.modal__loading { padding: 40px; text-align: center; color: var(--text-muted); }

/* Question of data-turbo-confirm (app.js), also on top of the modal dialog */
.confirm-dialog { width: min(420px, calc(100vw - 32px)); }
.confirm-dialog form { padding: 20px; }
.confirm-dialog__message { margin: 0 0 16px; overflow-wrap: anywhere; }

/* Links opened in an overlay instead of a new tab (Preferences, link_overlay_controller.js) */
.link-overlay {
    width: calc(100vw - 48px);
    max-width: 1400px;
    height: calc(100vh - 48px);
    max-height: none;
    padding: 0;
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    background: var(--surface);
    color: var(--text);
    box-shadow: var(--shadow-lg);
    overflow: hidden;
}
.link-overlay[open] { display: flex; flex-direction: column; }
.link-overlay::backdrop { background: rgb(10 14 22 / 0.45); backdrop-filter: blur(2px); }
.link-overlay__bar {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 8px 8px 16px;
    border-bottom: 1px solid var(--border);
}
.link-overlay__title { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 14px; }
.link-overlay__hint { color: var(--text-faint); font-size: 12px; }
.link-overlay__frame { flex: 1; width: 100%; border: 0; background: #fff; }
@media (max-width: 640px) {
    .link-overlay { width: 100vw; max-width: none; height: 100vh; border-radius: 0; }
    .link-overlay__hint { display: none; }
}

/* Type picker in "Add content" */
.type-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 10px; }
.type-card {
    display: grid;
    gap: 6px;
    padding: 14px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    color: var(--text);
}
.type-card:hover { border-color: var(--accent); background: var(--accent-soft); text-decoration: none; }
.type-card .icon { width: 22px; height: 22px; color: var(--accent); }
.type-card strong { font-size: 14px; }
.type-card span { color: var(--text-muted); font-size: 12.5px; }

.candidate-list { display: grid; gap: 8px; margin: 0 0 14px; padding: 0; list-style: none; }
.candidate {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 12px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    cursor: pointer;
}
.candidate:has(input:checked) { border-color: var(--accent); background: var(--accent-soft); }
.candidate small { display: block; color: var(--text-muted); overflow-wrap: anywhere; }

/* live feed suggestions under the address field (feed_suggest_controller.js) */
.feed-suggest { position: relative; }
.feed-suggest.is-loading input { background: var(--surface) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23888' stroke-width='2'%3E%3Cpath d='M21 12a9 9 0 1 1-6.2-8.6'%3E%3CanimateTransform attributeName='transform' type='rotate' from='0 12 12' to='360 12 12' dur='0.8s' repeatCount='indefinite'/%3E%3C/path%3E%3C/svg%3E") no-repeat right 10px center; }
.feed-suggest__panel:empty { display: none; }
.feed-suggest__panel { margin: -6px 0 14px; }
.feed-suggest__list {
    margin: 0;
    padding: 4px;
    list-style: none;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface);
}
.feed-suggest__option { padding: 8px 10px; border-radius: var(--radius-sm); cursor: pointer; }
.feed-suggest__option:hover, .feed-suggest__option[aria-selected="true"] { background: var(--accent-soft); }
.feed-suggest__option small { display: block; color: var(--text-muted); overflow-wrap: anywhere; }
.feed-suggest__error { margin: 0; color: var(--text-muted); font-size: .9em; }

.color-swatches { display: flex; flex-wrap: wrap; gap: 8px; }
.color-swatch { position: relative; }
.color-swatch input { position: absolute; opacity: 0; }
.color-swatch span {
    display: block;
    width: 28px;
    height: 28px;
    border: 2px solid var(--surface);
    border-radius: 50%;
    background: var(--box-color);
    box-shadow: 0 0 0 1px var(--border-strong);
    cursor: pointer;
}
.color-swatch input:checked + span { box-shadow: 0 0 0 2px var(--text); }
.color-swatch input:focus-visible + span { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ==========================================================================
   Empty dashboard
   ========================================================================== */
.empty {
    grid-column: 1 / -1;
    display: grid;
    justify-items: center;
    gap: 10px;
    padding: 64px 16px;
    color: var(--text-muted);
    text-align: center;
}
.empty > .icon { width: 40px; height: 40px; color: var(--text-faint); }
.empty h2 { color: var(--text); font-size: 18px; }

/* .flashes { padding: 12px var(--gutter) 0; } */ /* why: save space */

/* ==========================================================================
   Pages: preferences, site settings
   ========================================================================== */
.page { max-width: 760px; margin: 0 auto; padding: 24px var(--gutter) 64px; }
.page__title { margin: 0 0 4px; font-size: 22px; }
.page__lead { margin: 0 0 20px; color: var(--text-muted); }
.panel {
    margin-bottom: 16px;
    padding: 18px 20px 6px;
    border: var(--box-border-width) solid var(--box-border-color);
    border-radius: var(--radius-lg);
    background: var(--surface);
    box-shadow: var(--shadow-sm);
}
.panel--quiet { background: var(--surface-2); box-shadow: none; padding-bottom: 18px; }
.panel__title { margin: 0 0 14px; font-size: 15px; }
.panel__lead { margin: -8px 0 14px; }
.grid-2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 16px; }
@media (max-width: 560px) { .grid-2 { grid-template-columns: minmax(0, 1fr); } }

/*
 * Settings pages on wide screens: sections with a heading, each a grid of panels side by side
 * instead of one long column. A panel takes one column (min. 300px), --wide two, --full the row.
 */
.settings-section { margin-bottom: 28px; }
.settings-section__title { margin: 0 0 4px; font-size: 17px; }
.settings-section__lead { margin: 0 0 12px; color: var(--text-muted); font-size: 13px; }
.settings-section__title + .settings-grid { margin-top: 12px; }
.settings-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr)); gap: 16px; }
.settings-grid > .panel { margin-bottom: 0; }
.settings-grid--halves { grid-template-columns: repeat(auto-fit, minmax(min(100%, 380px), 1fr)); }
.settings-grid > .panel--wide { grid-column: span 2; }
.settings-grid > .panel--full { grid-column: 1 / -1; }
@media (max-width: 700px) { .settings-grid > .panel--wide { grid-column: 1 / -1; } }
/* fields side by side inside a wide panel */
.field-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 200px), 1fr)); gap: 0 16px; }
/* a short form in one row: fields and button aligned at the bottom */
.form-row { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 0 16px; }
.form-row > .field:first-child { flex: 1 1 280px; max-width: 460px; }
.form-row > .field--checkbox { min-height: 38px; align-content: center; }
.form-row > .btn { margin-bottom: 14px; }
/* the save buttons of a long form stay in reach while scrolling */
.form-actions--sticky {
    position: sticky;
    bottom: 0;
    z-index: 5;
    margin: 0 calc(-1 * var(--gutter)) 28px;
    padding: 12px var(--gutter);
    border-top: 1px solid var(--border);
    background: color-mix(in srgb, var(--bg) 88%, transparent);
    backdrop-filter: blur(6px);
}

.range { display: flex; align-items: center; gap: 10px; }
.field .range input[type="range"] { flex: 1; height: auto; padding: 0; border: 0; box-shadow: none; accent-color: var(--accent); }
.range output { min-width: 4.2em; color: var(--text-muted); font-size: 13px; text-align: right; font-variant-numeric: tabular-nums; }

/* three groups side by side: style and font, shapes, motion */
.appearance__groups { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr)); gap: 0 28px; }
.appearance__fields { margin: 0; padding: 0; border: 0; min-width: 0; }
.appearance__fields:disabled { opacity: .5; }
.appearance__legend {
    margin-bottom: 12px;
    padding: 0 0 6px;
    width: 100%;
    border-bottom: 1px solid var(--border);
    color: var(--text-muted);
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
}
.appearance__site-default { margin-bottom: 18px; }
.appearance__accent { display: flex; align-items: center; gap: 8px; }
.appearance__accent label { font-weight: 500; }
.field .appearance__accent input[type="color"] { width: 48px; height: 30px; padding: 2px; cursor: pointer; }

.env-list { display: flex; flex-wrap: wrap; gap: 6px; margin: 0; padding: 0; list-style: none; }
.env-list code { padding: 2px 6px; border-radius: var(--radius-sm); background: var(--surface-sunken); font-size: 12px; }

/* ==========================================================================
   Admin area (templates/admin/)
   ========================================================================== */
.page--wide { max-width: 1120px; }
/* the admin pages in three groups: the site, the accounts, the running installation */
.admin-nav {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 6px;
    margin: 0 0 22px;
    padding: 4px;
    border-radius: var(--radius);
    background: var(--surface-sunken);
}
.admin-nav__group { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; }
.admin-nav__group + .admin-nav__group { padding-left: 6px; border-left: 1px solid var(--border); }
.admin-nav__label {
    padding: 0 6px 0 8px;
    color: var(--text-faint);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .05em;
    text-transform: uppercase;
}
@media (max-width: 640px) {
    .admin-nav { flex-direction: column; }
    .admin-nav__group + .admin-nav__group { padding-left: 0; border-left: 0; }
    .admin-nav__label { min-width: 72px; }
}
.admin-nav__item {
    padding: 6px 12px;
    border-radius: var(--radius-sm);
    color: var(--text-muted);
    font-weight: 500;
}
.admin-nav__item:hover { color: var(--text); text-decoration: none; }
.admin-nav__item[aria-current="page"] { background: var(--surface); color: var(--text); box-shadow: var(--shadow); }

.form-actions--start { justify-content: flex-start; }
.panel--padded { padding-bottom: 18px; }
.steps { margin: 0 0 10px; padding-left: 20px; }
.steps li { margin-bottom: 4px; }
.panel--highlight { border-color: var(--accent); background: var(--accent-soft); padding-bottom: 18px; }
.btn--small { height: 28px; padding: 0 10px; font-size: 12.5px; }
.btn--small .icon { width: 14px; height: 14px; }
.badge {
    display: inline-block;
    margin-left: 6px;
    padding: 1px 7px;
    border-radius: 999px;
    background: var(--surface-sunken);
    color: var(--text-muted);
    font-size: 11.5px;
    font-weight: 600;
    vertical-align: 1px;
}
.badge--accent { background: var(--accent-soft); color: var(--accent); }
.badge--danger { background: var(--danger-soft); color: var(--danger); }
.badge--success { color: var(--success); }

.copy-field { display: flex; gap: 8px; }
.copy-field .input { flex: 1; min-width: 0; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12.5px; }

.table-wrap {
    margin-bottom: 16px;
    border: var(--box-border-width) solid var(--box-border-color);
    border-radius: var(--radius-lg);
    background: var(--surface);
    box-shadow: var(--shadow-sm);
    overflow: hidden;
}
.table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.table th {
    padding: 10px 12px;
    border-bottom: 1px solid var(--border);
    background: var(--surface-2);
    color: var(--text-muted);
    font-size: 12px;
    font-weight: 600;
    text-align: left;
    white-space: nowrap;
}
.table td { padding: 10px 12px; border-bottom: 1px solid var(--border); vertical-align: middle; }
.table tbody tr:last-child td { border-bottom: 0; }
.table__num { text-align: right; font-variant-numeric: tabular-nums; }
.table__actions { text-align: right; white-space: nowrap; }
.table__actions .inline-form + .inline-form { margin-left: 4px; }
.table__error { display: flex; gap: 4px; align-items: flex-start; margin-top: 4px; color: var(--danger); font-size: 12px; }
.table__error .icon { flex: none; width: 14px; height: 14px; margin-top: 1px; }
.toolbar { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 10px; margin-bottom: 14px; }
.segmented__link { padding: 5px 12px; border-radius: 6px; color: var(--text-muted); font-weight: 500; }
.segmented__link:hover { color: var(--text); text-decoration: none; }
.segmented__link[aria-current="page"] { background: var(--surface); color: var(--text); box-shadow: var(--shadow); }
.table__sub { display: block; max-width: 420px; overflow: hidden; color: var(--text-faint); font-size: 12px; text-overflow: ellipsis; white-space: nowrap; }
/* a sentence rather than a name: wraps instead of being cut off */
.table__sub--wrap { max-width: 64ch; white-space: normal; }
.input--small { width: auto; height: 30px; padding: 0 8px; font-size: 13px; }

/* phones: every row becomes a small card, cells labelled by data-label */
@media (max-width: 760px) {
    .table thead { display: none; }
    .table, .table tbody, .table tr, .table td { display: block; }
    .table tr { padding: 10px 12px; border-bottom: 1px solid var(--border); }
    .table td { display: flex; justify-content: space-between; gap: 12px; padding: 3px 0; border: 0; text-align: right; }
    .table td[data-label]::before { content: attr(data-label); color: var(--text-muted); font-size: 12px; text-align: left; }
    .table td:first-child { display: block; text-align: left; }
    .table td:first-child::before { content: none; }
    .table__actions { justify-content: flex-start; flex-wrap: wrap; padding-top: 8px; }
}

/* status page */
.status-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 0 16px; }
.status-grid .panel { padding-bottom: 14px; }
.status-line { display: flex; align-items: center; gap: 8px; margin: -4px 0 10px; }
.status-dot { width: 10px; height: 10px; border-radius: 50%; background: var(--text-faint); }
.status-dot--ok { background: var(--success); box-shadow: 0 0 0 3px color-mix(in srgb, var(--success) 20%, transparent); }
.status-dot--bad { background: var(--danger); box-shadow: 0 0 0 3px var(--danger-soft); }
.facts { display: grid; grid-template-columns: auto 1fr; gap: 6px 12px; margin: 0 0 10px; font-size: 13px; }
.facts dt { color: var(--text-muted); }
.facts dd { margin: 0; text-align: right; font-variant-numeric: tabular-nums; }
.section-title { margin: 12px 0 10px; font-size: 16px; }
.panel code { font-size: 11.5px; overflow-wrap: anywhere; }
