/* /Components/Layout/MainLayout.razor.rz.scp.css */
/* Scoped styles minimal — main styling in app.css */
/* /Components/Layout/NavMenu.razor.rz.scp.css */
/* Scoped styles minimal — main styling in app.css */
/* /Components/Layout/ReconnectModal.razor.rz.scp.css */
.components-reconnect-first-attempt-visible[b-o2t3o07k2w],
.components-reconnect-repeated-attempt-visible[b-o2t3o07k2w],
.components-reconnect-failed-visible[b-o2t3o07k2w],
.components-pause-visible[b-o2t3o07k2w],
.components-resume-failed-visible[b-o2t3o07k2w],
.components-rejoining-animation[b-o2t3o07k2w] {
    display: none;
}

#components-reconnect-modal.components-reconnect-show .components-reconnect-first-attempt-visible[b-o2t3o07k2w],
#components-reconnect-modal.components-reconnect-show .components-rejoining-animation[b-o2t3o07k2w],
#components-reconnect-modal.components-reconnect-paused .components-pause-visible[b-o2t3o07k2w],
#components-reconnect-modal.components-reconnect-resume-failed .components-resume-failed-visible[b-o2t3o07k2w],
#components-reconnect-modal.components-reconnect-retrying[b-o2t3o07k2w],
#components-reconnect-modal.components-reconnect-retrying .components-reconnect-repeated-attempt-visible[b-o2t3o07k2w],
#components-reconnect-modal.components-reconnect-retrying .components-rejoining-animation[b-o2t3o07k2w],
#components-reconnect-modal.components-reconnect-failed[b-o2t3o07k2w],
#components-reconnect-modal.components-reconnect-failed .components-reconnect-failed-visible[b-o2t3o07k2w] {
    display: block;
}


#components-reconnect-modal[b-o2t3o07k2w] {
    background-color: white;
    width: 20rem;
    margin: 20vh auto;
    padding: 2rem;
    border: 0;
    border-radius: 0.5rem;
    box-shadow: 0 3px 6px 2px rgba(0, 0, 0, 0.3);
    opacity: 0;
    transition: display 0.5s allow-discrete, overlay 0.5s allow-discrete;
    animation: components-reconnect-modal-fadeOutOpacity-b-o2t3o07k2w 0.5s both;
    &[open]

{
    animation: components-reconnect-modal-slideUp-b-o2t3o07k2w 1.5s cubic-bezier(.05, .89, .25, 1.02) 0.3s, components-reconnect-modal-fadeInOpacity-b-o2t3o07k2w 0.5s ease-in-out 0.3s;
    animation-fill-mode: both;
}

}

#components-reconnect-modal[b-o2t3o07k2w]::backdrop {
    background-color: rgba(0, 0, 0, 0.4);
    animation: components-reconnect-modal-fadeInOpacity-b-o2t3o07k2w 0.5s ease-in-out;
    opacity: 1;
}

@keyframes components-reconnect-modal-slideUp-b-o2t3o07k2w {
    0% {
        transform: translateY(30px) scale(0.95);
    }

    100% {
        transform: translateY(0);
    }
}

@keyframes components-reconnect-modal-fadeInOpacity-b-o2t3o07k2w {
    0% {
        opacity: 0;
    }

    100% {
        opacity: 1;
    }
}

@keyframes components-reconnect-modal-fadeOutOpacity-b-o2t3o07k2w {
    0% {
        opacity: 1;
    }

    100% {
        opacity: 0;
    }
}

.components-reconnect-container[b-o2t3o07k2w] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1rem;
}

#components-reconnect-modal p[b-o2t3o07k2w] {
    margin: 0;
    text-align: center;
}

#components-reconnect-modal button[b-o2t3o07k2w] {
    border: 0;
    background-color: #6b9ed2;
    color: white;
    padding: 4px 24px;
    border-radius: 4px;
}

    #components-reconnect-modal button:hover[b-o2t3o07k2w] {
        background-color: #3b6ea2;
    }

    #components-reconnect-modal button:active[b-o2t3o07k2w] {
        background-color: #6b9ed2;
    }

.components-rejoining-animation[b-o2t3o07k2w] {
    position: relative;
    width: 80px;
    height: 80px;
}

    .components-rejoining-animation div[b-o2t3o07k2w] {
        position: absolute;
        border: 3px solid #0087ff;
        opacity: 1;
        border-radius: 50%;
        animation: components-rejoining-animation-b-o2t3o07k2w 1.5s cubic-bezier(0, 0.2, 0.8, 1) infinite;
    }

        .components-rejoining-animation div:nth-child(2)[b-o2t3o07k2w] {
            animation-delay: -0.5s;
        }

@keyframes components-rejoining-animation-b-o2t3o07k2w {
    0% {
        top: 40px;
        left: 40px;
        width: 0;
        height: 0;
        opacity: 0;
    }

    4.9% {
        top: 40px;
        left: 40px;
        width: 0;
        height: 0;
        opacity: 0;
    }

    5% {
        top: 40px;
        left: 40px;
        width: 0;
        height: 0;
        opacity: 1;
    }

    100% {
        top: 0px;
        left: 0px;
        width: 80px;
        height: 80px;
        opacity: 0;
    }
}
/* /Components/Pages/ApiKeysPage.razor.rz.scp.css */
/* The one-time key and its copy control on one line; the key wraps rather than
   pushing the button off the dialog. */
.key-reveal[b-jirbxp20km] {
    display: flex;
    gap: var(--space-2);
    align-items: center;
    margin-top: var(--space-2);
}
.key-reveal code[b-jirbxp20km] {
    flex: 1;
    min-width: 0;
    word-break: break-all;
    user-select: all;
}
/* Standing instruction rather than an error: the key is shown once, and by the time the copy
   is refused there is no server round-trip left to render a message with. */
.key-copy-hint[b-jirbxp20km] {
    margin-top: var(--space-2);
    font-size: 0.8rem;
    color: var(--text-muted);
}
.key-usage[b-jirbxp20km] {
    margin-top: var(--space-2);
}
/* /Components/Pages/AppearancePage.razor.rz.scp.css */
/* Appearance — screen-local spacing. Tokens only (docs/08). */

.appearance-field[b-9aw2lcbnye] {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.appearance-field > label[b-9aw2lcbnye] {
    font-size: 0.8rem;
    font-weight: 500;
    color: var(--text-muted);
}

/* The help line belongs to the editor below it, so it sits tight against the
   label and keeps its distance from the box. */
.appearance-hint[b-9aw2lcbnye] {
    max-width: 68ch;
    line-height: 1.5;
}

.appearance-hint code[b-9aw2lcbnye] {
    font-size: 0.95em;
    padding: 1px var(--space-1);
    border-radius: var(--radius-sm);
    background: var(--surface-sunken);
    color: var(--text-muted);
}
/* /Components/Pages/BillingSubscriptionDetailPage.razor.rz.scp.css */
/* The service's terms, read at a glance: label above value, wrapping into as many columns as
   fit. A table would promise sorting and comparison that a single record cannot deliver. */
.service-facts[b-0fjnhw37mv] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: var(--space-4, 16px);
    margin: 0;
}

.service-facts dt[b-0fjnhw37mv] {
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    opacity: 0.65;
    margin-bottom: 2px;
}

.service-facts dd[b-0fjnhw37mv] {
    margin: 0;
}

.service-facts-full[b-0fjnhw37mv] {
    grid-column: 1 / -1;
}

/* ===== "Record invoice" — the half you copy out of =====
   Rows, not a form: a label, the value in a monospaced face so digits and domains can be
   checked character by character, and the button that takes it. The tight gap sets it
   apart from the fields below, which are the half you type into. */
.invoice-copy[b-0fjnhw37mv] {
    display: grid;
    gap: 6px;
    margin-bottom: var(--space-5, 20px);
}

.invoice-copy .hint[b-0fjnhw37mv] {
    margin-bottom: var(--space-2, 8px);
}

.copy-row[b-0fjnhw37mv] {
    display: grid;
    grid-template-columns: 120px minmax(0, 1fr) auto;
    align-items: center;
    gap: 8px;
}

.copy-row--text[b-0fjnhw37mv] {
    align-items: start;
}

.copy-row-label[b-0fjnhw37mv] {
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    opacity: 0.65;
}

.copy-row-value[b-0fjnhw37mv],
.copy-text[b-0fjnhw37mv] {
    font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
    font-size: 0.85rem;
    overflow-wrap: anywhere;
}

.copy-row-actions[b-0fjnhw37mv] {
    display: inline-flex;
    gap: 2px;
}

/* One line each, with room for a second when a long domain wraps. */
.copy-text[b-0fjnhw37mv] {
    width: 100%;
    min-height: 2.6em;
    resize: vertical;
    line-height: 1.5;
}

/* The modal is narrower than a page: two columns is as far as the fields go. */
.invoice-form[b-0fjnhw37mv] {
    gap: 10px 16px;
}

@media (max-width: 600px) {
    .copy-row[b-0fjnhw37mv] {
        grid-template-columns: minmax(0, 1fr) auto;
    }

    .copy-row-label[b-0fjnhw37mv] {
        grid-column: 1 / -1;
    }
}
/* /Components/Pages/BlocksPage.razor.rz.scp.css */
/* Blocks list. Tokens only; see docs/08-design-system.md. */

.blocks-table .row-title[b-agi6g8w5po] {
    font-weight: 500;
    text-decoration: none;
}

/* The preview is markup, so it reads as code and never wraps a row to two lines. */
.block-preview[b-agi6g8w5po] {
    display: block;
    max-width: 60ch;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--text-muted);
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 0.78rem;
}

.blocks-table a.row-action[b-agi6g8w5po] {
    color: var(--text-muted);
    text-decoration: none;
}

.blocks-table a.row-action:hover[b-agi6g8w5po] {
    color: var(--text);
    opacity: 1;
}
/* /Components/Pages/CategoriesPage.razor.rz.scp.css */
/* Categories list (audit F7, A12). */

.visibility-cell[b-aev7gd7lpg] {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1);
}

.slug-link[b-aev7gd7lpg],
.slug-plain[b-aev7gd7lpg] {
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;
  font-size: 0.8rem;
}
.slug-plain[b-aev7gd7lpg] { color: var(--text-muted); }

/* Header cell for the quiet row actions: named for screen readers, blank on screen. */
.visually-hidden[b-aev7gd7lpg] {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
/* /Components/Pages/CategoryDetailPage.razor.rz.scp.css */
/* The note belongs to both checkboxes, so it sits clear of either column. */
.visibility-note[b-8bsgm9e40h] {
  margin-top: var(--space-3);
  padding-top: var(--space-3);
  border-top: 1px solid var(--border);
}
/* /Components/Pages/DashboardPage.razor.rz.scp.css */
/* Dashboard — screen-local layout. Tokens only (docs/08).

   The rest of the dashboard's look lives in app.css (.dashboard-stats,
   .dashboard-layout, .dashboard-publish-*, .dashboard-info-panel); this file
   only carries what is specific to this screen: the rhythm between the two
   blocks in the main column, one heading style shared with the side column,
   and the column widths that stop VIEWS and the dates from crowding. */

/* ----- Main column rhythm ----- */
/* "Traffic" and "Recent published posts" were flush against each other with
   nothing between them. Spacing separates them, not a box or a rule. */
.dashboard-main[b-krelajeygj] {
    display: flex;
    flex-direction: column;
    gap: var(--space-6);
}

.dash-block[b-krelajeygj] {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    min-width: 0;
}

.dash-block-header[b-krelajeygj] {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--space-3);
    min-height: 28px;
}

/* One heading style for the whole screen: the same uppercase, muted section
   heading the side column already uses for WEBSITE INFO / DRAFT ARTICLES
   (docs/08 §6). Sentence-case h3 next to uppercase h4 read as two systems. */
.dash-section-title[b-krelajeygj] {
    margin: 0;
    font-size: 0.82rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
}

.dash-section-meta[b-krelajeygj] {
    font-size: 0.8rem;
    color: var(--text-subtle);
    margin-left: auto;
}

.dash-period-switch[b-krelajeygj] {
    display: flex;
    gap: var(--space-1);
}

/* ----- Tables ----- */
/* Numbers and dates shrink to their content so the title column takes the
   slack, instead of every column sharing the width equally. */
.dash-table th.num[b-krelajeygj],
.dash-table td.num[b-krelajeygj] {
    width: 1%;
    white-space: nowrap;
    padding-left: var(--space-5);
}

.dash-table th.dash-col-date[b-krelajeygj],
.dash-table td.dash-col-date[b-krelajeygj] {
    width: 1%;
    white-space: nowrap;
    padding-left: var(--space-5);
    font-variant-numeric: tabular-nums;
    color: var(--text-muted);
}

.dash-cell-muted[b-krelajeygj] {
    color: var(--text-muted);
}

.dash-row-icon[b-krelajeygj] {
    color: var(--text-subtle);
}

/* ----- Side column ----- */
/* The publish widget is now the only place on the screen that states the
   publishing date, so it also carries the way into revision history. */
.dashboard-publish-link[b-krelajeygj] {
    padding-left: var(--space-4);
    font-size: 0.8rem;
}

.dash-key[b-krelajeygj] {
    color: var(--text-muted);
    white-space: nowrap;
    vertical-align: top;
}

/* Domains were a ragged stack of anchors. One list, one row per domain, the
   badge pinned right so the addresses line up whatever their length. */
.domain-list[b-krelajeygj] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}

.domain-list li[b-krelajeygj] {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    min-width: 0;
}

.domain-list a[b-krelajeygj] {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
}

/* The badge belongs to the address beside it, so it sits right after the (possibly
   truncated) name rather than being pushed to the far edge of the cell. */
.domain-list .status-badge[b-krelajeygj] {
    flex-shrink: 0;
}

.dash-info-action[b-krelajeygj] {
    margin-top: var(--space-3);
}

/* "Set up" beside "Not billed" — a link, not a button: the row states a fact and offers
   the one thing you would do about it. */
.dash-billing-link[b-krelajeygj] {
    margin-left: var(--space-2);
    font-size: 0.82rem;
}
/* /Components/Pages/ExportImportPage.razor.rz.scp.css */
/* Export / Import — screen-local form layout. Tokens only (docs/08).

   This screen used a layout found nowhere else in the app: labels beside their
   controls and a raw file input. Everything below puts the label above the
   control, the same way the rest of the forms do. */

.ei-title[b-29h689d91d] {
    margin: 0;
    font-size: 1.05rem;
    font-weight: 600;
    color: var(--text);
}

.ei-subtitle[b-29h689d91d] {
    margin: 0 0 var(--space-2);
    font-size: 0.82rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
}

.ei-lead[b-29h689d91d] {
    max-width: 72ch;
    line-height: 1.5;
}

/* ----- Fields ----- */
.ei-field[b-29h689d91d] {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.ei-label[b-29h689d91d] {
    font-size: 0.8rem;
    font-weight: 500;
    color: var(--text-muted);
}

.ei-help[b-29h689d91d] {
    max-width: 72ch;
    line-height: 1.5;
}

.ei-mode[b-29h689d91d] {
    margin: 0;
    display: flex;
    align-items: center;
    gap: var(--space-3);
    font-size: 0.875rem;
}

/* ----- Content-type checkboxes -----
   grid-auto-flow: row is the default, but it is stated here because the point of
   the rule is the reading order: across, then down (audit B8). */
.ei-checkgrid[b-29h689d91d] {
    display: grid;
    grid-auto-flow: row;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: var(--space-3) var(--space-5);
    max-width: 720px;
}

/* ----- File picker -----
   The native control is kept for its file dialog and its keyboard behaviour, but
   it is taken out of the layout; the label around it is what you see and click. */
.ei-file[b-29h689d91d] {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    flex-wrap: wrap;
}

.ei-file-button[b-29h689d91d] {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    height: 34px;
    padding: 0 var(--space-4);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius);
    background: var(--surface-raised);
    color: var(--text);
    font-size: 0.85rem;
    font-weight: 500;
    cursor: pointer;
    transition: background var(--transition), border-color var(--transition);
}

.ei-file-button:hover[b-29h689d91d] {
    border-color: var(--accent);
    color: var(--accent);
}

.ei-file-button:focus-within[b-29h689d91d] {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

/* InputFile renders the <input> itself, so it needs ::deep to be reached from
   this component's scoped stylesheet. */
.ei-file-button[b-29h689d91d]  input[type="file"] {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}

.ei-file-name[b-29h689d91d] {
    font-size: 0.85rem;
    color: var(--text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 40ch;
}

.ei-file-name.is-empty[b-29h689d91d] {
    color: var(--text-subtle);
}

/* ----- Summary of a loaded file ----- */
.ei-summary[b-29h689d91d] {
    display: grid;
    grid-auto-flow: row;
    grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
    gap: var(--space-1) var(--space-5);
    margin: var(--space-2) 0 0;
}

.ei-summary > div[b-29h689d91d] {
    display: flex;
    gap: var(--space-2);
    font-size: 0.85rem;
    min-width: 0;
}

.ei-summary dt[b-29h689d91d] {
    color: var(--text-muted);
    white-space: nowrap;
}

.ei-summary dd[b-29h689d91d] {
    margin: 0;
    font-weight: 600;
}

/* ----- Actions ----- */
.ei-actions[b-29h689d91d] {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex-wrap: wrap;
    margin-top: var(--space-1);
}

/* A quiet text control for "Select all" / "Clear" / "Change" — these are not
   buttons competing with the primary action. */
.ei-link[b-29h689d91d] {
    border: none;
    background: none;
    padding: 0;
    font: inherit;
    font-size: 0.8rem;
    color: var(--accent);
    cursor: pointer;
}

.ei-link:hover[b-29h689d91d] {
    color: var(--accent-hover);
    text-decoration: underline;
}

.ei-actions .ei-link[b-29h689d91d] {
    margin-right: var(--space-2);
}

/* ----- Merge diff ----- */
.ei-diff[b-29h689d91d] {
    background: var(--surface-sunken);
    border-radius: var(--radius);
    padding: var(--space-4);
}

.ei-diff ul[b-29h689d91d] {
    margin: 0 0 var(--space-3);
    padding-left: var(--space-5);
    font-size: 0.85rem;
    color: var(--text-muted);
}

.ei-diff-heading[b-29h689d91d] {
    margin: var(--space-3) 0 var(--space-1);
    font-size: 0.8rem;
    font-weight: 600;
}

.ei-diff-added[b-29h689d91d] { color: var(--ok); }
.ei-diff-updated[b-29h689d91d] { color: var(--warn); }
.ei-diff-unchanged[b-29h689d91d] { color: var(--text-subtle); }
/* /Components/Pages/FileManagerPage.razor.rz.scp.css */
/* File manager (docs/08 design system, docs/09 §C).

   Everything here is tokens only. The page deliberately owns its grid, card and
   panel rules instead of the older global .folder-card / .file-card pair, because
   folders and files now share one card shape and one set of column tracks. The
   global .file-card rules stay in app.css for FilePicker and PostImageGallery. */

/* The files panel is a .stack grid; rows keep their natural height instead of
   stretching to fill the panel (the dropzone especially). */
.file-manager-files[b-yhq9tbd5mw] { align-content: start; }

.fm-sr[b-yhq9tbd5mw] {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ===== Toolbar: folder path + view toggle ===== */
.fm-toolbar[b-yhq9tbd5mw] {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.fm-breadcrumb[b-yhq9tbd5mw] {
  display: flex;
  align-items: center;
  gap: 2px;
  flex-wrap: wrap;
  min-width: 0;
}
.fm-breadcrumb-item[b-yhq9tbd5mw] {
  border: none;
  background: transparent;
  font: inherit;
  font-size: 0.85rem;
  color: var(--text-muted);
  cursor: pointer;
  padding: 4px 8px;
  border-radius: var(--radius-sm);
  max-width: 200px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  transition: background var(--transition), color var(--transition);
}
.fm-breadcrumb-item:hover[b-yhq9tbd5mw] {
  background: var(--accent-soft);
  color: var(--text);
}
.fm-breadcrumb-item:last-child[b-yhq9tbd5mw] {
  color: var(--text);
  font-weight: 600;
}
.fm-breadcrumb-item > i.icon[b-yhq9tbd5mw] { margin: 0 4px 0 0; }
.fm-breadcrumb-sep[b-yhq9tbd5mw] {
  color: var(--text-subtle);
  font-size: 0.75em;
  user-select: none;
}
.fm-breadcrumb-sep i.icon[b-yhq9tbd5mw] { margin: 0; }

.fm-view-toggle[b-yhq9tbd5mw] {
  display: inline-flex;
  gap: 2px;
  padding: 2px;
  background: var(--surface-raised);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  flex: none;
}
.fm-view-toggle button[b-yhq9tbd5mw] {
  border: none;
  background: transparent;
  color: var(--text-muted);
  border-radius: var(--radius-sm);
  width: 30px;
  height: 26px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background var(--transition), color var(--transition);
}
.fm-view-toggle button i.icon[b-yhq9tbd5mw] { margin: 0; }
.fm-view-toggle button:hover[b-yhq9tbd5mw] { color: var(--text); }
.fm-view-toggle button.active[b-yhq9tbd5mw] {
  background: var(--accent-soft);
  color: var(--accent);
}

/* ===== Inputs (docs/08 §9) — the one input shape this page uses ===== */
.fm-input[b-yhq9tbd5mw] {
  width: 100%;
  min-height: 34px;
  padding: 0 var(--space-3);
  background: var(--surface-raised);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  color: var(--text);
  font: inherit;
  font-size: 0.875rem;
}
.fm-input[b-yhq9tbd5mw]::placeholder { color: var(--text-subtle); }
.fm-input:focus-visible[b-yhq9tbd5mw] {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-color: var(--accent);
}
.fm-input--sm[b-yhq9tbd5mw] {
  min-height: 28px;
  font-size: 0.82rem;
  padding: 0 var(--space-2);
}
.fm-input[readonly][b-yhq9tbd5mw] { color: var(--text-muted); }

/* ===== New folder (only on screen while in use) ===== */
.fm-newfolder[b-yhq9tbd5mw] {
  display: grid;
  gap: var(--space-2);
  padding: var(--space-3);
  background: var(--surface-raised);
  border-radius: var(--radius);
}
.fm-newfolder > label[b-yhq9tbd5mw] {
  font-size: 0.8rem;
  font-weight: 500;
  color: var(--text-muted);
}
.fm-newfolder-row[b-yhq9tbd5mw] {
  display: flex;
  gap: var(--space-2);
  align-items: center;
}
.fm-newfolder-row .fm-input[b-yhq9tbd5mw] { max-width: 260px; }

/* ===== Upload ===== */
.fm-dropzone[b-yhq9tbd5mw] {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-4);
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius);
  color: var(--text-muted);
  font-size: 0.875rem;
  cursor: pointer;
  transition: border-color var(--transition), color var(--transition), background var(--transition);
}
.fm-dropzone:hover[b-yhq9tbd5mw] {
  border-color: var(--accent);
  color: var(--text);
  background: var(--accent-soft);
}
.fm-dropzone i.icon[b-yhq9tbd5mw] { margin: 0; }
.fm-dropzone:focus-within[b-yhq9tbd5mw] {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.fm-uploads[b-yhq9tbd5mw] {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--space-2);
}
.fm-upload-line[b-yhq9tbd5mw] {
  display: flex;
  justify-content: space-between;
  gap: var(--space-3);
  font-size: 0.82rem;
  margin-bottom: 4px;
}
.fm-upload-name[b-yhq9tbd5mw] {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--text);
}
.fm-progress[b-yhq9tbd5mw] {
  height: 4px;
  border-radius: var(--radius-full);
  background: var(--surface-sunken);
  overflow: hidden;
}
.fm-progress-bar[b-yhq9tbd5mw] {
  height: 100%;
  background: var(--accent);
  transition: width 200ms ease;
}
.fm-progress.is-done .fm-progress-bar[b-yhq9tbd5mw] { background: var(--ok); }
.fm-progress.is-error .fm-progress-bar[b-yhq9tbd5mw] { background: var(--err); }

.fm-meta[b-yhq9tbd5mw] {
  font-size: 0.76rem;
  color: var(--text-muted);
}

/* ===== One grid, one card shape for folders and files ===== */
/* 176px is the narrowest a card can be and still fit its footer: the size on the
   left and three 28px row-actions on the right. */
.fm-grid[b-yhq9tbd5mw] {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(176px, 1fr));
  gap: var(--space-3);
}

/* A download action is a link, not a button — it has to look like its neighbours. */
.row-actions a.row-action[b-yhq9tbd5mw] {
  text-decoration: none;
  flex: none;
}

.fm-card[b-yhq9tbd5mw] {
  display: flex;
  flex-direction: column;
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  transition: border-color var(--transition), box-shadow var(--transition);
}
.fm-card:hover[b-yhq9tbd5mw] { border-color: var(--border-strong); }
.fm-card.is-selected[b-yhq9tbd5mw] {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px var(--accent-soft);
}

/* The primary action is a real button covering the thumbnail and the name, so a
   click anywhere in the body of the card opens the folder / selects the file and
   can never hit a secondary control (audit C1). */
.fm-open[b-yhq9tbd5mw] {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  width: 100%;
  padding: var(--space-2) var(--space-2) 0;
  border: none;
  background: transparent;
  font: inherit;
  color: var(--text);
  text-align: left;
  cursor: pointer;
}
.fm-open:disabled[b-yhq9tbd5mw] { cursor: default; }
.fm-open:focus-visible[b-yhq9tbd5mw] {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
  border-radius: var(--radius);
}

.fm-thumb[b-yhq9tbd5mw] {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 4 / 3;
  border-radius: var(--radius);
  background: var(--surface-sunken);
  overflow: hidden;
}
/* One rule for every aspect ratio: the whole image, centred, on the same well —
   no card crops and no card letterboxes differently from its neighbour (C11). */
.fm-thumb img[b-yhq9tbd5mw] {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}
.fm-thumb > i.icon[b-yhq9tbd5mw] {
  margin: 0;
  font-size: 1.9em;
  color: var(--text-subtle);
}
.fm-thumb--folder > i.icon[b-yhq9tbd5mw] {
  color: var(--text-muted);
  transition: color var(--transition);
}
.fm-card:hover .fm-thumb--folder > i.icon[b-yhq9tbd5mw] { color: var(--accent); }

/* Truncate — a filename never wraps mid-word; the full name is in the tooltip (C4). */
.fm-name[b-yhq9tbd5mw] {
  display: block;
  font-size: 0.82rem;
  font-weight: 500;
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.fm-foot[b-yhq9tbd5mw] {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  min-height: 32px;
  padding: 0 var(--space-2) var(--space-1) var(--space-2);
}
/* The actions keep their width; the size label gives way if the card is narrow. */
.fm-foot > .fm-meta[b-yhq9tbd5mw] {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.fm-foot > .row-actions[b-yhq9tbd5mw] { flex: none; }
/* Same reveal rule as table row actions (docs/08 §9). */
.fm-card:hover .row-actions[b-yhq9tbd5mw],
.fm-card:focus-within .row-actions[b-yhq9tbd5mw] { opacity: 1; }
@media (hover: none) {
  .fm-card .row-actions[b-yhq9tbd5mw] { opacity: 1; }
}

.fm-rename[b-yhq9tbd5mw] {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-2);
}
.fm-rename .fm-input[b-yhq9tbd5mw] { min-width: 0; }
.fm-rename-actions[b-yhq9tbd5mw] { opacity: 1; }

/* ===== List view: folders and files in one table (C7) ===== */
.fm-table th.fm-col-thumb[b-yhq9tbd5mw],
.fm-table td.fm-col-thumb[b-yhq9tbd5mw] {
  width: 44px;
  padding-right: var(--space-2);
}
.fm-rowthumb[b-yhq9tbd5mw] {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: var(--radius-sm);
  background: var(--surface-sunken);
  overflow: hidden;
}
.fm-rowthumb img[b-yhq9tbd5mw] {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}
.fm-rowthumb > i.icon[b-yhq9tbd5mw] {
  margin: 0;
  font-size: 0.9em;
  color: var(--text-subtle);
}
.fm-rowthumb--folder > i.icon[b-yhq9tbd5mw] { color: var(--text-muted); }
.fm-cell-name[b-yhq9tbd5mw] {
  display: block;
  max-width: 320px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 500;
}
.fm-table tbody tr.is-selected[b-yhq9tbd5mw] {
  background: var(--accent-soft);
  box-shadow: inset 2px 0 0 var(--accent);
}

/* ===== Details modal (C2/C3) =====
   The details used to be a rail next to the grid: a second panel of its own height
   that never lined up with the files panel, and whose appearance reflowed the grid.
   As a modal it owns the whole viewport's attention and neither problem exists. */
.ui.dimmer.modals > .ui.modal.fm-modal[b-yhq9tbd5mw] {
  width: min(820px, 100%);
  max-width: 100%;
}
/* The dialog takes focus when it opens so Escape closes it; that focus is a
   mechanism, not a control, so it draws no ring. */
.fm-modal:focus[b-yhq9tbd5mw] { outline: none; }
/* A long filename truncates instead of pushing the close button off the header. */
/* The close sits inside the header rather than beside it (#248), so the header is
   the positioning context and has to leave room for the button on the right. */
.fm-modal > .header[b-yhq9tbd5mw] {
  position: relative;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  padding-right: calc(var(--space-6) + var(--space-3));
}
.fm-modal-close[b-yhq9tbd5mw] {
  position: absolute;
  top: 50%;
  right: var(--space-3);
  transform: translateY(-50%);
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: none;
  background: transparent;
  border-radius: var(--radius-sm);
  color: var(--text-muted);
  font: inherit;
  cursor: pointer;
  transition: background var(--transition), color var(--transition);
}
.fm-modal-close:hover[b-yhq9tbd5mw] {
  background: var(--surface-sunken);
  color: var(--text);
}
.fm-modal-close i.icon[b-yhq9tbd5mw] { margin: 0; }
.fm-modal-close:focus-visible[b-yhq9tbd5mw] {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* Two columns so the dialog reads wide and short rather than tall and narrow:
   what the file *is* on the left, what you can change about it on the right. */
.fm-detail-grid[b-yhq9tbd5mw] {
  display: grid;
  grid-template-columns: minmax(0, 260px) minmax(0, 1fr);
  gap: var(--space-5);
  align-items: start;
}
.fm-detail-media[b-yhq9tbd5mw],
.fm-detail-fields[b-yhq9tbd5mw] {
  display: grid;
  gap: var(--space-4);
  min-width: 0;
}
/* Only short viewports scroll the body. Clipping it unconditionally would also clip
   the folder dropdown's menu, which opens inside this box. */
@media (max-height: 760px) {
  .fm-modal > .content[b-yhq9tbd5mw] {
    max-height: calc(100vh - 190px);
    overflow-y: auto;
  }
}
@media (max-width: 720px) {
  .fm-detail-grid[b-yhq9tbd5mw] { grid-template-columns: minmax(0, 1fr); }
}

.fm-preview[b-yhq9tbd5mw] {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 4 / 3;
  background: var(--surface-sunken);
  border-radius: var(--radius);
  overflow: hidden;
}
.fm-preview img[b-yhq9tbd5mw] {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  display: block;
}
.fm-preview > i.icon[b-yhq9tbd5mw] {
  margin: 0;
  font-size: 3em;
  color: var(--text-subtle);
}

.fm-facts[b-yhq9tbd5mw] {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--space-1) var(--space-3);
  margin: 0;
  font-size: 0.82rem;
  align-items: baseline;
}
.fm-facts dt[b-yhq9tbd5mw] {
  color: var(--text-muted);
  font-weight: 500;
}
.fm-facts dd[b-yhq9tbd5mw] {
  margin: 0;
  color: var(--text);
  min-width: 0;
  overflow-wrap: anywhere;
}

.fm-url[b-yhq9tbd5mw] {
  display: grid;
  gap: var(--space-1);
}
.fm-url > label[b-yhq9tbd5mw] {
  font-size: 0.8rem;
  font-weight: 500;
  color: var(--text-muted);
}
.fm-url-row[b-yhq9tbd5mw] {
  display: flex;
  align-items: center;
  gap: var(--space-1);
}
.fm-url-row .row-action[b-yhq9tbd5mw] { flex: none; text-decoration: none; }
.fm-url-row a.row-action[b-yhq9tbd5mw] { color: var(--text-muted); }

/* The grid card and the table row never show the public address, but the copy handler reads
   what it copies out of the DOM — this is where it reads it from. */
.fm-copy-source[b-yhq9tbd5mw] { display: none; }

.fm-form[b-yhq9tbd5mw] { margin: 0; }
.fm-form .field[b-yhq9tbd5mw] { margin: 0 0 var(--space-3) !important; }
.fm-form .field:last-child[b-yhq9tbd5mw] { margin-bottom: 0 !important; }
.fm-move[b-yhq9tbd5mw] {
  display: flex;
  gap: var(--space-2);
  align-items: center;
}

/* Delete is fenced off from Save (docs/08 §9): pushed to the far left of the row,
   the whole width of the dialog away from the buttons that keep the file. */
.fm-modal > .actions.fm-modal-actions[b-yhq9tbd5mw] {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-3);
}
.fm-modal-actions[b-yhq9tbd5mw]  .action-danger { margin-right: auto; }

@media (max-width: 900px) {
  .fm-cell-name[b-yhq9tbd5mw] { max-width: 180px; }
}
/* /Components/Pages/PageDetailPage.razor.rz.scp.css */
/* Page detail — audit D1 (one save), D5 (Add section), D6 (reorder hint),
   D8 (unsaved changes + sticky save), B1 (checkbox rows).
   Tokens only; see docs/08-design-system.md. */

/* ----- Content / Settings tabs -----
   The strip itself is the shared `.design-tabs` from app.css; what belongs to this
   screen is the state a tab has to carry, because one save writes both tabs and a
   required field can sit on the tab you are not looking at. */
.tab-flag[b-4blbims0ie] {
    width: 7px;
    height: 7px;
    margin-left: var(--space-2);
    border-radius: var(--radius-full);
    background: var(--warn);
}

.tab-flag--error[b-4blbims0ie] {
    background: var(--err);
}

/* A dot is easy to miss on a tab you are not looking at, so a refused save colours
   the whole label. */
.design-tabs button.has-error[b-4blbims0ie] {
    color: var(--err);
}

.form-error[b-4blbims0ie] {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin: 0;
    padding: var(--space-2) var(--space-3);
    border-radius: var(--radius);
    background: var(--err-soft);
    color: var(--err);
    font-size: 0.82rem;
}

.form-error i.icon[b-4blbims0ie] {
    margin: 0;
}

/* ----- Panel head ----- */
.panel-head[b-4blbims0ie] {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--space-4);
}

.panel-head-text[b-4blbims0ie] {
    min-width: 0;
}

.panel-title[b-4blbims0ie] {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin: 0;
    font-size: 0.82rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
}

.panel-count[b-4blbims0ie] {
    padding: 1px var(--space-2);
    border-radius: var(--radius-sm);
    background: var(--surface-raised);
    color: var(--text-muted);
    font-size: 0.72rem;
    letter-spacing: 0;
}

body[data-theme="light"] .panel-count[b-4blbims0ie] {
    background: var(--surface-sunken);
}

.panel-sub[b-4blbims0ie] {
    margin: var(--space-1) 0 0;
    color: var(--text-muted);
    font-size: 0.8rem;
}

/* ----- D6: reorder help reads as help, not as a stray sentence ----- */
.list-hint[b-4blbims0ie] {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin: 0;
    padding: var(--space-2) var(--space-3);
    border-radius: var(--radius);
    background: var(--surface-raised);
    color: var(--text-muted);
    font-size: 0.8rem;
}

body[data-theme="light"] .list-hint[b-4blbims0ie] {
    background: var(--surface-sunken);
}

.list-hint i.icon[b-4blbims0ie] {
    margin: 0;
    color: var(--text-subtle);
}

/* ----- Section list ----- */
.section-list[b-4blbims0ie] {
    display: grid;
    gap: var(--space-2);
}

/* D5: a normal button, under the list, sized to its label. */
.section-add[b-4blbims0ie] {
    display: flex;
}

/* ----- Form details ----- */
.check-row[b-4blbims0ie] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2) var(--space-3);
    padding-top: var(--space-1);
}

/* .check-help and .field-note take their look and their spacing from the global
   help-text rule (app.css, docs/08 §10). */
.field-note code[b-4blbims0ie] {
    padding: 1px 5px;
    border-radius: var(--radius-sm);
    background: var(--surface-raised);
    font-size: 0.78rem;
}

body[data-theme="light"] .field-note code[b-4blbims0ie] {
    background: var(--surface-sunken);
}

/* ----- D8: unsaved changes, always in reach ----- */
.save-bar[b-4blbims0ie] {
    position: sticky;
    bottom: var(--space-3);
    z-index: 30;
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-lg);
    background: var(--surface-raised);
    box-shadow: var(--shadow);
}

body[data-theme="light"] .save-bar[b-4blbims0ie] {
    background: var(--surface);
}

.save-bar-state[b-4blbims0ie] {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    color: var(--text);
    font-size: 0.85rem;
    font-weight: 600;
    white-space: nowrap;
}

.save-bar-dot[b-4blbims0ie] {
    width: 8px;
    height: 8px;
    border-radius: var(--radius-full);
    background: var(--warn);
}

.save-bar-hint[b-4blbims0ie] {
    color: var(--text-muted);
    font-size: 0.8rem;
}

.save-bar-actions[b-4blbims0ie] {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    margin-left: auto;
}

@media (max-width: 700px) {
    .save-bar[b-4blbims0ie] {
        flex-wrap: wrap;
    }

    .save-bar-hint[b-4blbims0ie] {
        display: none;
    }
}
/* /Components/Pages/PagesPage.razor.rz.scp.css */
/* Pages list — audit D6 (reorder hint), D9 (information-poor list, invisible
   homepage slug). Tokens only; see docs/08-design-system.md. */

.sr-only[b-bfuro3pczl] {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

/* ----- D6: the reorder hint is a line of help, not a stray sentence ----- */
.list-hint[b-bfuro3pczl] {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin: 0;
    padding: var(--space-2) var(--space-3);
    border-radius: var(--radius);
    background: var(--surface-raised);
    color: var(--text-muted);
    font-size: 0.8rem;
}

body[data-theme="light"] .list-hint[b-bfuro3pczl] {
    background: var(--surface-sunken);
}

.list-hint i.icon[b-bfuro3pczl] {
    margin: 0;
    color: var(--text-subtle);
}

/* ----- Table ----- */
.pages-table .col-grip[b-bfuro3pczl] {
    width: 28px;
    padding-right: 0;
}

.pages-table td.drag-handle[b-bfuro3pczl] {
    width: 28px;
    cursor: grab;
    color: var(--text-subtle);
}

.pages-table td.drag-handle i.icon[b-bfuro3pczl] {
    margin: 0;
}

.pages-table .row-title[b-bfuro3pczl] {
    font-weight: 500;
    text-decoration: none;
}

.pages-table td .status-badge[b-bfuro3pczl] {
    margin-left: var(--space-2);
}

.pages-table td:nth-child(5) .status-badge[b-bfuro3pczl] {
    margin-left: 0;
}

/* ----- D9: the homepage's "/" was a one-character click target ----- */
.path-chip[b-bfuro3pczl] {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    min-width: 44px;
    padding: 2px var(--space-2);
    border-radius: var(--radius-sm);
    background: var(--surface-raised);
    color: var(--text-muted);
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 0.78rem;
    text-decoration: none;
    transition: background var(--transition), color var(--transition);
}

body[data-theme="light"] .path-chip[b-bfuro3pczl] {
    background: var(--surface-sunken);
}

a.path-chip:hover[b-bfuro3pczl] {
    color: var(--accent);
    opacity: 1;
}

.path-chip i.icon[b-bfuro3pczl] {
    margin: 0;
    font-size: 0.72rem;
    opacity: 0.7;
}

.path-chip.is-static[b-bfuro3pczl] {
    cursor: default;
}

/* Row actions are anchors here, so they need the button's quiet colouring. */
.pages-table a.row-action[b-bfuro3pczl] {
    color: var(--text-muted);
    text-decoration: none;
}

.pages-table a.row-action:hover[b-bfuro3pczl] {
    color: var(--text);
    opacity: 1;
}
/* /Components/Pages/PostDetailPage.razor.rz.scp.css */
/* Post editor (audit E1–E8).

   The screen is a writing surface with a publishing rail beside it, not a form
   with an editor squeezed into a corner. The main column takes whatever the rail
   does not need, and the rail is a stack of small cards that all share one
   rhythm: heading, one line of help, the controls. */

.post-editor[b-smha4ipquy] {
  /* padding rather than margin: .admin-content zeroes the margin of whatever
     follows the page header, expecting a single merged panel. */
  padding-top: var(--space-4);
  display: grid;
  grid-template-columns: minmax(0, 1fr) 340px;
  gap: var(--space-4);
  align-items: start;
}

.post-editor-main[b-smha4ipquy],
.post-editor-rail[b-smha4ipquy] {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  min-width: 0;
}

/* ----- Main column ----- */

.post-write[b-smha4ipquy] {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-5);
  min-width: 0;
}

/* The title is the heading of the thing being written, so it is typed like one. */
.post-title-field[b-smha4ipquy]  input {
  font-size: 1.1rem;
  font-weight: 600;
  height: 42px;
}

.post-slug-field[b-smha4ipquy] {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  max-width: 480px;
}
.post-slug-field[b-smha4ipquy]  input {
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;
  font-size: 0.82rem;
}

.post-gallery-panel[b-smha4ipquy] {
  padding: var(--space-4);
}
/* The gallery sits under the editor now, so it no longer needs the rule that
   fenced it off from the field above it in the old rail. */
.post-gallery-panel[b-smha4ipquy]  .post-image-gallery {
  margin-top: 0;
  padding-top: 0;
  border-top: none;
}

/* ----- Publishing rail ----- */

.rail-card[b-smha4ipquy] {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-4);
  min-width: 0;
}

.rail-title[b-smha4ipquy] {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
  margin: 0;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
}
/* "This site only" (audit E6) is a note about the card, not part of its name. */
.rail-title-flag[b-smha4ipquy] {
  font-size: 0.66rem;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
}

/* .field-hint itself is global now (app.css, docs/08 §10) — one look and one
   distance for every hint in the app. */

.rail-fields[b-smha4ipquy] {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.rail-field[b-smha4ipquy] {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
}
.rail-field--spaced[b-smha4ipquy] { margin-top: var(--space-1); }
.rail-label[b-smha4ipquy] {
  font-size: 0.8rem;
  font-weight: 500;
  color: var(--text-muted);
}

/* One width for every control in the rail (audit B3): the date, the time, the
   select and the text inputs all line up on the same two edges. */
.post-editor-rail[b-smha4ipquy]  .ui.input,
.post-editor-rail[b-smha4ipquy]  .ui.selection.dropdown,
.post-editor-rail[b-smha4ipquy]  input:not([type="checkbox"]):not([type="radio"]) {
  width: 100%;
  min-width: 0;
}
.post-editor-rail[b-smha4ipquy]  .field { width: 100%; }
/* The date+time pair is one field, so it shares one row. */
.rail-field[b-smha4ipquy]  .ui.input + .ui.input { margin-top: var(--space-2); }

/* ----- Status ----- */

.rail-status[b-smha4ipquy] {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
}
.rail-status-note[b-smha4ipquy] {
  font-size: 0.78rem;
  color: var(--text-muted);
}
.rail-action[b-smha4ipquy]  .ui.button {
  width: 100%;
  margin: 0;
}

/* ----- Categories ----- */

.rail-checklist[b-smha4ipquy] {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  max-height: 260px;
  overflow-y: auto;
}
.rail-check[b-smha4ipquy] {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  min-width: 0;
}
.rail-check[b-smha4ipquy]  .ui.checkbox { min-width: 0; }
.rail-main-flag[b-smha4ipquy] {
  flex-shrink: 0;
  padding: 1px 6px;
  font-size: 0.66rem;
}

@media (max-width: 1180px) {
  .post-editor[b-smha4ipquy] { grid-template-columns: minmax(0, 1fr); }
}
/* /Components/Pages/PostsPage.razor.rz.scp.css */
/* Posts list (audit F5, A12–A14). */

.posts-table td.cell-empty[b-d5n4qmfshg] {
  color: var(--text-subtle);
}

/* Header cell for the quiet row actions: named for screen readers, blank on screen. */
.visually-hidden[b-d5n4qmfshg] {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Pagination is a quiet footer, not a row of buttons — and it only renders when
   there is more than one page (audit F5). */
.pager[b-d5n4qmfshg] {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-3);
}
.pager-position[b-d5n4qmfshg] {
  font-size: 0.8rem;
  color: var(--text-muted);
}
.pager[b-d5n4qmfshg]  .ui.button.disabled,
.pager[b-d5n4qmfshg]  .ui.button[disabled] {
  opacity: 0.4;
  box-shadow: none;
  cursor: default;
}
/* /Components/Pages/RedirectsPage.razor.rz.scp.css */
/* Redirects list — screen-local details. Tokens only (docs/08). */

/* Source and destination are addresses: they should not wrap mid-path, and the
   "Prefix" marker belongs beside the source, not stuck to it. */
.redirect-source[b-pcmyqbrmbp] {
    white-space: nowrap;
}

td .status-badge[b-pcmyqbrmbp] {
    margin-left: var(--space-2);
}

/* The Kind cell's badge is the whole cell — no extra offset there. */
td:nth-child(3) .status-badge[b-pcmyqbrmbp] {
    margin-left: 0;
}

.redirect-note[b-pcmyqbrmbp] {
    color: var(--text-muted);
}
/* /Components/Pages/RevisionsPage.razor.rz.scp.css */
/* Revisions & Publish — screen-local details. Tokens only (docs/08). */

/* "Revision history" was bold body text; it is a section heading, and it uses
   the one section-heading style (docs/08 §6). */
.revisions-section-title[b-k2vrwopmrp] {
    margin: var(--space-4) 0 0;
    font-size: 0.82rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
}

/* The action group is right-aligned in the card header and its destructive
   member sits at the far left of the group, behind the .action-sep hairline. */
.deploy-card-actions[b-k2vrwopmrp] {
    align-items: center;
}

.revisions-date[b-k2vrwopmrp] {
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
    color: var(--text-muted);
}

.revisions-note[b-k2vrwopmrp] {
    color: var(--text-muted);
}
/* /Components/Pages/RoleDetailPage.razor.rz.scp.css */
/* Permissions run across-then-down, the way a reader expects, instead of the
   column-major order the browser produced from a plain two-column grid (audit B8). */
.permission-grid[b-wk0msenjsx] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: var(--space-4) var(--space-5);
}
.permission[b-wk0msenjsx] {
    display: grid;
    gap: var(--space-1);
    min-width: 0;
}

/* Select-all sits with the group's name, not among the checkboxes it controls:
   a quiet text button, not a fourth button style. */
.group-toggle[b-wk0msenjsx] {
    margin-top: var(--space-2);
    padding: 0;
    border: none;
    background: none;
    color: var(--accent);
    font-family: inherit;
    font-size: 0.8rem;
    font-weight: 500;
    cursor: pointer;
    transition: color var(--transition);
}
.group-toggle:hover[b-wk0msenjsx] {
    color: var(--accent-hover);
    text-decoration: underline;
}
.group-toggle:focus-visible[b-wk0msenjsx] {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
    border-radius: var(--radius-sm);
}
/* /Components/Pages/UserDetailPage.razor.rz.scp.css */
/* Checkboxes are their own group with their own air, so they never read as the
   tail of the input above them (audit B1). Each one carries the sentence that
   explains what granting it actually means. */
.checkbox-stack[b-oz7r4vmucu] {
    display: grid;
    gap: var(--space-4);
}
.checkbox-row[b-oz7r4vmucu] {
    display: grid;
    gap: var(--space-1);
}

/* The section's own action sits under its fields, fenced from the page-level
   Save in the header — one section, one thing it does. */
.section-action[b-oz7r4vmucu] {
    margin-top: var(--space-3);
}

/* Website + role pickers share one column track so the two selects are the same
   width and both are labelled (audit A9). */
.role-assign[b-oz7r4vmucu] {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) auto;
    gap: var(--space-3);
    align-items: end;
    max-width: 640px;
}
.role-assign > label[b-oz7r4vmucu] {
    display: grid;
    gap: var(--space-2);
    min-width: 0;
    font-size: 0.8rem;
    font-weight: 500;
    color: var(--text-muted);
}

/* Fomantic gives a selection dropdown its own min-width; the grid track decides
   here, otherwise the two selects come out different widths again. */
.role-assign[b-oz7r4vmucu]  .ui.dropdown {
    width: 100%;
    min-width: 0;
}

@media (max-width: 720px) {
    .role-assign[b-oz7r4vmucu] {
        grid-template-columns: minmax(0, 1fr);
    }
}
/* /Components/Pages/UsersPage.razor.rz.scp.css */
/* A table cell that holds a label plus one or more badges: they line up on one
   baseline with the standard 8px gap instead of colliding (docs/08 §5). */
.cell-row[b-f6zn4kn512] {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    flex-wrap: wrap;
    min-width: 0;
}
/* /Components/Pages/WebsiteDetailPage.razor.rz.scp.css */
/* A one-line note above the domain table: a sentence, not a coloured message box —
   nothing has gone wrong here (docs/08 §1.2). */
.domains-hint i.icon[b-ekea9yj1dv] {
    margin-right: var(--space-1);
}

/* A cell holding a link plus a badge keeps them on one baseline. */
.cell-row[b-ekea9yj1dv] {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    flex-wrap: wrap;
    min-width: 0;
}
/* /Components/Shared/HtmlCodeEditor.razor.rz.scp.css */
/* HTML editor field — audit D7: the editor started flush against the row above and
   reserved a fixed slab of empty space below a single line of markup. */

.code-field[b-m3dutuiedb] {
    display: grid;
    gap: var(--space-2);
    margin-top: var(--space-3);
    min-width: 0;
}

.code-field-head[b-m3dutuiedb] {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-3);
}

.code-field-label[b-m3dutuiedb] {
    font-size: 0.82rem;
    font-weight: 500;
    color: var(--text-muted);
}

.code-field-hint[b-m3dutuiedb] {
    font-size: 0.78rem;
    color: var(--text-subtle);
}

/* The editor grows with the content; past a screenful it scrolls inside its own box
   so one long section cannot bury the rest of the page. */
.code-field[b-m3dutuiedb]  .code-editor-wrap {
    max-height: 70vh;
}
/* /Components/Shared/PageHeader.razor.rz.scp.css */
/* Line 1 of the header is ONE slot with ONE typography, whichever of its two forms it
   takes (docs/05 §1.4). A list fills it with the sidebar region it belongs to
   ("PLATFORM"); a detail screen fills it with the way back out ("ADMIN › POSTS").
   Those used to be a coloured uppercase eyebrow and a small grey sentence, so the two
   kinds of screen shared no rhythm and a detail header read thinner and less anchored
   than a list's. They are the same size, weight, tracking and colour now — the trail
   differs only in being made of links, which is the whole point of it.
   Shared rules live in app.css; only what is specific to this slot is here. */

.eyebrow[b-dcz1u0ia0j],
.crumbs[b-dcz1u0ia0j] {
    margin: 0;
    font-size: 0.7rem;
    font-weight: 600;
    line-height: 1.25;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--accent);
}

.crumbs[b-dcz1u0ia0j] {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px;
}

/* Every segment is a place you can climb to, so every segment is a link and every
   segment is accent — including the last, which used to be the only one in --text and
   so read as the dead end of the trail rather than as the list it actually opens.
   Hover and focus add the underline instead of shifting the colour: at 0.7rem a shift
   to grey reads as the link going out, not as a pointer landing on it. */
.crumbs a[b-dcz1u0ia0j] {
    color: inherit;
    text-decoration: none;
}

.crumbs a:hover[b-dcz1u0ia0j],
.crumbs a:focus-visible[b-dcz1u0ia0j] {
    color: inherit;
    opacity: 1;
    text-decoration: underline;
    text-underline-offset: 3px;
}

/* The separator is furniture, not a place, so it is the one part that stays quiet.
   Tracking is cleared on it — 0.1em after a chevron reads as a stray gap. */
.crumbs .crumb-sep[b-dcz1u0ia0j] {
    color: var(--text-subtle);
    letter-spacing: 0;
    user-select: none;
}

/* A record's name can be long ("Rostlina měsíce: Šalvěj hajní 'Caradonna'") and must be
   able to wrap without ever reaching the buttons. A flex item defaults to
   min-width: auto, which is what lets a long title push its sibling off instead of
   wrapping — so the title column is explicitly allowed to shrink, the action group never
   is, and when the two no longer fit on one line the group drops to its own row rather
   than squeezing the title into a column two words wide. */
.content-header[b-dcz1u0ia0j] {
    flex-wrap: wrap;
    row-gap: var(--space-3);
}

.header-main[b-dcz1u0ia0j] {
    flex: 1 1 16rem;
    min-width: 0;
}

.header-main h2[b-dcz1u0ia0j] {
    overflow-wrap: break-word;
}

.topbar-actions[b-dcz1u0ia0j] {
    flex: 0 0 auto;
    flex-wrap: wrap;
    justify-content: flex-end;
    row-gap: 8px;
    margin-left: auto;
}
/* /Components/Shared/PostFilterBar.razor.rz.scp.css */
/* Posts filter bar (audit B3, F4): every control is one of two widths — a
   selector or the search box — instead of four arbitrary ones. */

.post-filters[b-ahzayzvt1b] {
  gap: var(--space-2);
}

.post-filter-control[b-ahzayzvt1b] {
  flex: 0 0 200px;
  min-width: 0;
}
/* 280px is the shared search-box width (app.css .toolbar-search, docs/08 §9);
   expressed as a flex basis because this bar wraps, not as a max-width. */
.post-filter-search[b-ahzayzvt1b] {
  flex: 0 1 280px;
}

.post-filter-control[b-ahzayzvt1b]  .ui.selection.dropdown,
.post-filter-control[b-ahzayzvt1b]  .ui.input,
.post-filter-control[b-ahzayzvt1b]  input {
  width: 100%;
  min-width: 0;
}

/* Fomantic positions the search icon over the first character; the app's own
   input padding wins over its indent rule, so the room is made here. */
.post-filter-search[b-ahzayzvt1b]  .ui.input > i.icon {
  left: 0;
  width: 32px;
  opacity: 0.55;
}
/* !important because the app's own control sizing sets padding the same way. */
.post-filter-search[b-ahzayzvt1b]  .ui.input > input {
  padding-left: 32px !important;
}

/* A way back out of a filtered list, only offered while there is something to clear. */
.post-filter-clear[b-ahzayzvt1b] {
  margin-left: auto;
  border: none;
  border-radius: var(--radius);
  padding: 6px 10px;
  background: transparent;
  color: var(--text-muted);
  font-family: inherit;
  font-size: 0.8rem;
  cursor: pointer;
  transition: background var(--transition), color var(--transition);
}
.post-filter-clear:hover[b-ahzayzvt1b] {
  background: var(--surface-raised);
  color: var(--text);
}
.post-filter-clear:focus-visible[b-ahzayzvt1b] {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

@media (max-width: 720px) {
  .post-filter-control[b-ahzayzvt1b],
  .post-filter-search[b-ahzayzvt1b] {
    flex: 1 1 100%;
  }
  .post-filter-clear[b-ahzayzvt1b] { margin-left: 0; }
}
/* /Components/Shared/PostImageGallery.razor.rz.scp.css */
/* A filename is a label, not a paragraph: one line, ellipsis, full name in the
   tooltip — the same rule the file manager uses (docs/09 C4). */
.file-name[b-xye7iq1u8a] {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  word-break: normal;
}
/* /Components/Shared/SectionEditor.razor.rz.scp.css */
/* Section card — audit D2 (collapsible), D3 (one field grid, one width),
   D4 (position, not SortOrder), B1 (checkboxes on their own row).
   Tokens only; see docs/08-design-system.md. */

.section-card[b-eflew8ndvi] {
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    background: var(--surface-raised);
    transition: border-color var(--transition);
}

body[data-theme="light"] .section-card[b-eflew8ndvi] {
    background: var(--surface);
}

.section-card.is-open[b-eflew8ndvi] {
    border-color: var(--border-strong);
}

/* ----- Collapsed summary: the whole row a 10-section page has to read ----- */
.section-summary[b-eflew8ndvi] {
    display: grid;
    grid-template-columns: auto auto minmax(0, 1fr) auto auto;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-1) var(--space-3);
}

.section-grip[b-eflew8ndvi] {
    display: inline-flex;
    align-items: center;
    color: var(--text-subtle);
    cursor: grab;
}

.section-grip i.icon[b-eflew8ndvi] {
    margin: 0;
}

.section-ordinal[b-eflew8ndvi] {
    min-width: 16px;
    text-align: right;
    color: var(--text-subtle);
    font-size: 0.78rem;
}

.section-toggle[b-eflew8ndvi] {
    display: flex;
    align-items: baseline;
    gap: var(--space-2);
    min-width: 0;
    padding: var(--space-3) var(--space-1);
    border: none;
    background: transparent;
    color: var(--text);
    font-family: inherit;
    font-size: 0.875rem;
    font-weight: 500;
    text-align: left;
    cursor: pointer;
}

.section-toggle:focus-visible[b-eflew8ndvi] {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
    border-radius: var(--radius-sm);
}

.section-toggle i.icon[b-eflew8ndvi] {
    margin: 0;
    width: 12px;
    color: var(--text-subtle);
    transition: color var(--transition);
}

.section-toggle:hover i.icon[b-eflew8ndvi] {
    color: var(--text);
}

.section-name[b-eflew8ndvi] {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.section-slug[b-eflew8ndvi] {
    color: var(--text-subtle);
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 0.76rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.section-flags[b-eflew8ndvi] {
    display: flex;
    align-items: center;
    gap: var(--space-2);
}

/* Quiet like a table's row actions: revealed by hovering the card, and always there
   for the keyboard and for touch. */
.section-actions[b-eflew8ndvi] {
    display: inline-flex;
    justify-content: flex-end;
    opacity: 0;
    transition: opacity var(--transition);
}

.section-card:hover .section-actions[b-eflew8ndvi],
.section-card:focus-within .section-actions[b-eflew8ndvi] {
    opacity: 1;
}

@media (hover: none) {
    .section-actions[b-eflew8ndvi] {
        opacity: 1;
    }
}

/* ----- Expanded editor -----
   The card opens on the HTML content. The five metadata fields are set once and then
   almost never changed, so they wait behind a disclosure instead of pushing the editor
   down the screen every time someone opens a section.

   The card is one surface with one left edge: the disclosure strip, the fields it
   opens and the editor all start at the same margin, and the only line between the
   two regions is a hairline. An inset well here put a second grey panel on top of the
   editor's own grey and a second left margin beside its label. */
.section-body[b-eflew8ndvi] {
    border-top: 1px solid var(--border);
}

/* The settings half of the body. The hairline belongs to the region, not to the
   button, so it stays put whether the fields are showing or not. */
.section-region[b-eflew8ndvi] {
    border-bottom: 1px solid var(--border);
}

/* Structure, not a chip: a full-width row like an accordion header, with the caret at
   the far end and the label on the same margin as everything below it. */
.section-settings-toggle[b-eflew8ndvi] {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    width: 100%;
    padding: var(--space-2) var(--space-3);
    border: none;
    background: transparent;
    color: var(--text-muted);
    font-family: inherit;
    font-size: 0.8rem;
    font-weight: 500;
    line-height: 1.2;
    text-align: left;
    cursor: pointer;
    transition: color var(--transition), background var(--transition);
}

.section-settings-toggle:hover[b-eflew8ndvi] {
    background: var(--surface);
    color: var(--text);
}

body[data-theme="light"] .section-settings-toggle:hover[b-eflew8ndvi] {
    background: var(--surface-sunken);
}

.section-settings-toggle:focus-visible[b-eflew8ndvi] {
    outline: 2px solid var(--accent);
    outline-offset: -2px;
}

.section-settings-toggle i.icon[b-eflew8ndvi] {
    margin: 0;
    width: auto;
    font-size: 0.9em;
    color: var(--text-subtle);
    transition: color var(--transition);
}

.section-settings-toggle:hover i.icon[b-eflew8ndvi] {
    color: var(--text-muted);
}

/* Same width as the summary row's chevron so the two disclosures line up as one
   family of controls. */
.section-settings-toggle i.section-settings-caret[b-eflew8ndvi] {
    width: 12px;
    text-align: left;
}

/* The badge sits at the end of the row, where the summary row above keeps its own
   badges — not wedged between the label and the chevron. */
.section-settings-flag[b-eflew8ndvi] {
    margin-left: auto;
}

.section-region.is-open .section-settings-label[b-eflew8ndvi] {
    color: var(--text);
}

/* No box of its own — the fields sit on the card, indented to the same margin as the
   label above them and the editor below. */
.section-settings[b-eflew8ndvi] {
    padding: 0 var(--space-3) var(--space-3);
}

.section-content[b-eflew8ndvi] {
    padding: var(--space-3);
}

/* The editor field carries a top margin for the forms it usually sits in; here the
   region's padding already provides it. */
.section-content[b-eflew8ndvi]  .code-field {
    margin-top: 0;
}

/* B1: a checkbox never shares a grid row with an input — it gets its own full row,
   so nothing floats at the top of a taller cell. */
.check-row[b-eflew8ndvi] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2) var(--space-5);
    padding-top: var(--space-1);
}

@media (max-width: 700px) {
    .section-slug[b-eflew8ndvi] {
        display: none;
    }
}
/* /Components/Shared/TinyMceEditor.razor.rz.scp.css */
/* The writing surface (audit E1).

   TinyMCE builds its own DOM next to the textarea, so everything below it is
   reached through ::deep. Height is driven by the viewport instead of TinyMCE's
   fixed ~250px box: a min-height leaves the user's own resize handle working,
   because a dragged inline height larger than the minimum still wins. */

.editor-field[b-jy48ifx5eg] {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  /* Lets the field shrink inside a grid track instead of widening it. */
  min-width: 0;
}

.editor-label[b-jy48ifx5eg] {
  font-size: 0.8rem;
  font-weight: 500;
  color: var(--text-muted);
}

.editor-field[b-jy48ifx5eg]  .tox.tox-tinymce {
  width: 100%;
  min-height: clamp(420px, 58vh, 900px);
  border-radius: var(--radius);
}

/* The fallback textarea (no TinyMCE on the page) gets the same presence. */
.editor-field textarea.code-editor[b-jy48ifx5eg] {
  min-height: clamp(420px, 58vh, 900px);
}

/* The status bar's element path printed a bare "p" under every article — a
   detail of the markup, not of the writing. Word count and the resize grip stay. */
.editor-field[b-jy48ifx5eg]  .tox .tox-statusbar__path {
  display: none;
}

@media (prefers-reduced-motion: reduce) {
  .editor-field[b-jy48ifx5eg]  .tox * {
    transition: none !important;
  }
}
/* /Components/Shared/ViewsTrend.razor.rz.scp.css */
/* The trend is a number, so its digits line up with the numbers above and below
   it in a column (docs/08 §6). */
.views-trend[b-b4iq7lf8ca] {
    font-variant-numeric: tabular-nums;
}
