/* CapstoneRichText — homemade WYSIWYG editor (contenteditable surface + toolbar).
   Everything is drawn from Bootstrap's theme-aware custom properties (--bs-*),
   so light/dark support falls out of the [data-bs-theme] switch with no
   per-theme rules here. Loaded by <capstone-head> after capstone-multiselect.css. */

.capstone-richtext-label {
    margin-bottom: 0.25rem;
}

/* The frame is the "form control": toolbar + surface share one border so the
   editor reads as a single field. Focus styling mirrors .form-control:focus via
   :focus-within (focus actually lives on the contenteditable surface). */
.capstone-richtext-frame {
    /* ReSharper disable once CssNotResolved */
    border: var(--bs-border-width, 1px) solid var(--bs-border-color, #dee2e6);
    /* ReSharper disable once CssNotResolved */
    border-radius: var(--bs-border-radius, 0.375rem);
    /* ReSharper disable once CssNotResolved */
    background-color: var(--bs-body-bg, #fff);
    /* Deliberately NO overflow: hidden — the toolbar's dropdown menus (styles,
       fonts, colors) must overlay content below the editor like any popup,
       not get clipped at the frame's bottom border. The toolbar's own top
       corners are rounded below instead. */
}

.capstone-richtext-frame:focus-within {
    /* ReSharper disable once CssNotResolved */
    border-color: var(--bs-primary, #007055);
    /* ReSharper disable once CssNotResolved */
    box-shadow: 0 0 0 0.25rem rgba(var(--bs-primary-rgb, 0, 112, 85), 0.25);
}

/* ── Toolbar ─────────────────────────────────────────────── */

.capstone-richtext-toolbar {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem;
    padding: 0.375rem;
    /* ReSharper disable once CssNotResolved */
    background-color: var(--bs-tertiary-bg, #f8f9fa);
    /* ReSharper disable once CssNotResolved */
    border-bottom: var(--bs-border-width, 1px) solid var(--bs-border-color, #dee2e6);
    /* Follow the frame's radius (frame can't overflow-clip us — see above). */
    /* ReSharper disable twice CssNotResolved */
    border-top-left-radius: calc(var(--bs-border-radius, 0.375rem) - var(--bs-border-width, 1px));
    border-top-right-radius: calc(var(--bs-border-radius, 0.375rem) - var(--bs-border-width, 1px));
}

/* Buttons live in .btn-group clusters; keep them compact and quiet. The
   pressed state comes from Bootstrap's .active on .btn-outline-secondary. */
.capstone-richtext-toolbar .btn {
    line-height: 1;
}

/* aria-disabled buttons (undo/redo with an empty stack, unlink outside a
   link) stay focusable for the roving tab order — dim them instead. */
.capstone-richtext-toolbar .capstone-richtext-btn-off {
    opacity: 0.4;
    pointer-events: none;
}

/* Bootstrap Icons ships no "unlink" glyph — strike the link icon with a
   diagonal rule in currentColor so it tracks button state/theme colors. */
.capstone-richtext-toolbar .capstone-richtext-unlink-icon {
    position: relative;
    display: inline-block;
}

.capstone-richtext-toolbar .capstone-richtext-unlink-icon::after {
    content: "";
    position: absolute;
    left: 10%;
    right: 10%;
    top: 50%;
    border-top: 2px solid currentColor;
    transform: rotate(-45deg);
}

/* ── Editing surface ─────────────────────────────────────── */

.capstone-richtext-surface {
    position: relative; /* anchors the absolutely-positioned placeholder */
    padding: 0.5rem 0.75rem;
    min-height: 10rem;
    overflow-y: auto;
    /* ReSharper disable once CssNotResolved */
    color: var(--bs-body-color, #212529);
    /* The frame owns focus presentation (:focus-within ring above). */
    outline: none;
    /* Long unbroken strings (pasted URLs) must wrap, not overflow the frame. */
    overflow-wrap: break-word;
}

/* Placeholder: shown while the sanitized value is empty (data-rt-empty is
   maintained by _syncValue). ::before keeps it out of the accessibility tree
   and out of the editable content. */
.capstone-richtext-surface[data-rt-empty]::before {
    content: attr(data-placeholder);
    /* ReSharper disable once CssNotResolved */
    color: var(--bs-secondary-color, #6c757d);
    pointer-events: none;
    position: absolute;
    padding-right: 0.75rem; /* mirror surface padding so it wraps the same */
}

/* Content typography inside the surface — spacing tuned so a fresh document
   (<p><br></p>) doesn't look taller than an empty input. */
.capstone-richtext-surface > :last-child {
    margin-bottom: 0;
}

/* Inserted images must never overflow the frame. */
.capstone-richtext-surface img {
    max-width: 100%;
    height: auto;
}

.capstone-richtext-surface blockquote {
    margin: 0 0 0.5rem;
    padding: 0.25rem 0 0.25rem 0.75rem;
    /* Quiet single-color rule, per the brand rules: loud gradients are for
       navbar/footer/page-title accents only. */
    /* ReSharper disable once CssNotResolved */
    border-left: 3px solid var(--bs-primary, #007055);
    /* ReSharper disable once CssNotResolved */
    color: var(--bs-secondary-color, #6c757d);
}

/* ── Link / image popovers ───────────────────────────────── */

.capstone-richtext-popbox {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem;
    padding: 0.375rem;
    /* ReSharper disable once CssNotResolved */
    background-color: var(--bs-tertiary-bg, #f8f9fa);
    /* ReSharper disable once CssNotResolved */
    border-bottom: var(--bs-border-width, 1px) solid var(--bs-border-color, #dee2e6);
}

.capstone-richtext-popbox .form-control {
    max-width: 20rem;
}

/* Keep the buttons on one line while the inputs flex. */
.capstone-richtext-popbox .btn {
    flex-shrink: 0;
    white-space: nowrap;
}

/* ── Formatting menus (styles / fonts / colors / sizes) ──── */

/* Live labels on the styles/family/size toggles — cap width so a long value
   ("Times New Roman") doesn't stretch the toolbar. */
.capstone-richtext-toolbar .capstone-richtext-menu-label {
    display: inline-block;
    max-width: 7.5rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    vertical-align: bottom;
}

.capstone-richtext-colormenu {
    min-width: 12rem;
}

.capstone-richtext-swatches {
    display: grid;
    grid-template-columns: repeat(5, 1.5rem);
    gap: 0.375rem;
    padding: 0.5rem 1rem;
}

/* Swatches also carry .dropdown-item (for Bootstrap's arrow-key menu
   navigation), so re-assert the grid-button geometry its block styling would
   otherwise stretch. The swatch's background is an inline style, which wins
   over .dropdown-item's hover/active background repaints by specificity. */
.capstone-richtext-swatch {
    width: 1.5rem;
    height: 1.5rem;
    padding: 0;
    /* ReSharper disable once CssNotResolved */
    border: var(--bs-border-width, 1px) solid var(--bs-border-color, #dee2e6);
    /* ReSharper disable once CssNotResolved */
    border-radius: var(--bs-border-radius-sm, 0.25rem);
    cursor: pointer;
}

.capstone-richtext-swatch:hover,
.capstone-richtext-swatch:focus-visible {
    /* ReSharper disable once CssNotResolved */
    outline: 2px solid var(--bs-primary, #007055);
    outline-offset: 1px;
}

/* The "Default" reset item's chip: filled with currentColor, i.e. "whatever
   the theme's normal text color is" — the same visual convention as the
   toolbar indicator bar when no explicit color is set. */
.capstone-richtext-default-chip {
    display: inline-block;
    width: 1rem;
    height: 1rem;
    /* ReSharper disable twice CssNotResolved */
    border: var(--bs-border-width, 1px) solid var(--bs-border-color, #dee2e6);
    border-radius: var(--bs-border-radius-sm, 0.25rem);
    background-color: currentColor;
}

/* Current-color bar under the Font/Background color button icons: tracks the
   color at the caret (see _updateToolbar). Absolutely positioned into the
   button's own padding so the toggle stays exactly as tall as its neighbors.
   With no explicit color at the caret ("Default") it falls back to
   currentColor — i.e. it reads as "text-colored", which is what Default means. */
.capstone-richtext-color-stack {
    position: relative;
    display: inline-block;
    line-height: 1;
}

.capstone-richtext-color-indicator {
    position: absolute;
    left: 50%;
    bottom: -3px;
    transform: translateX(-50%);
    width: 1.05em;
    height: 3px;
    border-radius: 1px;
    background-color: currentColor;
}

/* Windows High Contrast (forced-colors) wipes author backgrounds — and a
   swatch's background IS its meaning, so the grid would render as ten
   identical blank buttons. Color swatches are the spec's canonical
   forced-color-adjust exception: keep the real colors, and draw the border/
   focus ring in system colors so the buttons stay visibly interactive. */
@media (forced-colors: active) {
    .capstone-richtext-swatch,
    .capstone-richtext-color-indicator {
        forced-color-adjust: none;
    }

    .capstone-richtext-swatch {
        border: 1px solid CanvasText;
    }

    .capstone-richtext-swatch:hover,
    .capstone-richtext-swatch:focus-visible {
        outline: 2px solid Highlight;
    }
}

/* ── Validation (validate() / validateForm) ──────────────── */

/* Theme-aware form tokens only, per the validation color rules — never raw
   --bs-danger/--bs-success as text. The state border must also survive
   :focus-within (the brand-green focus ring must not win on flagged frames),
   so the focused variants re-assert the border and tint the ring. */
.capstone-richtext-frame.is-invalid,
.capstone-richtext-frame.is-invalid:focus-within {
    /* ReSharper disable once CssNotResolved */
    border-color: var(--bs-form-invalid-border-color, #dc3545);
}

.capstone-richtext-frame.is-invalid:focus-within {
    /* ReSharper disable once CssNotResolved */
    box-shadow: 0 0 0 0.25rem rgba(var(--bs-danger-rgb, 220, 53, 69), 0.25);
}

.capstone-richtext-frame.is-valid,
.capstone-richtext-frame.is-valid:focus-within {
    /* ReSharper disable once CssNotResolved */
    border-color: var(--bs-form-valid-border-color, #198754);
}

.capstone-richtext-frame.is-valid:focus-within {
    /* ReSharper disable once CssNotResolved */
    box-shadow: 0 0 0 0.25rem rgba(var(--bs-success-rgb, 25, 135, 84), 0.25);
}

/* The "Required" badge under the frame (role="alert", shown by showValidation). */
.capstone-richtext-validation {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    margin-top: 0.25rem;
    font-size: 0.875rem;
    /* ReSharper disable once CssNotResolved */
    color: var(--bs-form-invalid-color, #dc3545);
}

/* ── Save footer / load state ────────────────────────────── */

.capstone-richtext-footer {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    gap: 0.75rem;
    margin-top: 0.375rem;
}

.capstone-richtext-save-status {
    font-size: 0.875rem;
    /* ReSharper disable once CssNotResolved */
    color: var(--bs-secondary-color, #6c757d);
}

.capstone-richtext-save-status-error {
    /* Theme-aware invalid token, per the validation color rules — never raw --bs-danger. */
    /* ReSharper disable once CssNotResolved */
    color: var(--bs-form-invalid-color, #dc3545);
}

/* While load()/read() is in flight the surface dims; the last-wins generation
   token in the JS makes concurrent edits harmless, so editing stays enabled. */
.capstone-richtext[data-loading] .capstone-richtext-surface {
    opacity: 0.6;
}

.capstone-richtext-read-error {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    margin-top: 0.25rem;
    font-size: 0.875rem;
    /* ReSharper disable once CssNotResolved */
    color: var(--bs-form-invalid-color, #dc3545);
}

.capstone-richtext-read-error-retry {
    padding: 0 0.25rem;
    font-size: 0.875rem;
    text-decoration: none;
}

/* ── Disabled state ──────────────────────────────────────── */

.capstone-richtext[data-disabled] .capstone-richtext-frame {
    /* ReSharper disable once CssNotResolved */
    background-color: var(--bs-secondary-bg, #e9ecef);
}

.capstone-richtext[data-disabled] .capstone-richtext-surface {
    /* ReSharper disable once CssNotResolved */
    color: var(--bs-secondary-color, #6c757d);
}
