/* The "what's on your mind" post/group-post compose form (see formCreatePost in
   templates/_macros/form.html.twig): a borderless look for its inputs, requested
   over the default Bootstrap/ux-dropzone borders. */
.post-compose-form .form-control,
.post-compose-form .form-select,
.post-compose-form .dropzone-container,
.post-compose-form .input-group-text,
.post-compose-form .btn {
    border: none;
}

.post-compose-form .form-select {
    background-color: var(--bs-body-bg);
}

.post-compose-form textarea.form-control {
    border-bottom: 1px solid var(--bs-border-color);
}

/* Used with the textarea-autogrow Stimulus controller: the textarea grows to fit typed
   content instead of showing an internal scrollbar, up to this max-height, then scrolls. */
.textarea-autogrow {
    max-height: 400px;
    overflow-y: auto;
}

/* Rounded-pill search input with a magnifying-glass icon overlaid inside it (used by a plain
   .input-group-text prepend can't reproduce, since that renders as a separate bordered segment
   rather than an icon sitting inside the pill). */
.search-input-wrap {
    position: relative;
}

.search-input-wrap .search-input-icon {
    position: absolute;
    top: 50%;
    left: 0.9rem;
    transform: translateY(-50%);
    pointer-events: none;
}

.search-input-wrap .search-input-icon ~ .form-control {
    padding-left: 2.5rem;
}

.upload-chip {
    width: 80px;
    height: 80px;
}

.upload-chip-remove {
    width: 20px;
    height: 20px;
    line-height: 1;
}

.chat-thread-messages {
    max-height: 60vh;
    overflow-y: auto;
    /* .chat-bubble rows are full-width (see below), not floated/capped-width bubbles, so this
       container should never need to scroll sideways - overflow-x is set explicitly rather than
       left to its browser-computed default. Per the CSS Overflow spec, when only overflow-y is set
       to a scrolling value, overflow-x's initial "visible" computes to "auto" too, which is what
       silently turned any wide content (e.g. a long unbroken URL) into a horizontal scrollbar here. */
    overflow-x: hidden;
    padding: 0.25rem 0.5rem;
}

/* Each message is a full-width row (not a left/right-floated bubble) - readability at this panel's
   narrow width comes from alternating row backgrounds and a sender name/time header, not from
   squeezing text into a max-width bubble. overflow-wrap is inherited, so it also covers
   .chat-bubble-body and any attachment filename below it. */
.chat-bubble {
    border-radius: 0.5rem;
    margin-bottom: 0.25rem;
    overflow-wrap: anywhere;
}

.chat-bubble-meta {
    margin-bottom: 0.15rem;
}

/* Edit/Unsend menu (see _message.html.twig) - only ever meaningful on your own messages, and
   chat_controller.js only adds chat-bubble-mine client-side, so this stays hidden until that
   classification actually runs rather than briefly showing on every message. */
.chat-bubble-actions {
    display: none;
}

.chat-bubble-mine .chat-bubble-actions {
    display: inline-block;
}

.chat-bubble-body {
    white-space: pre-line;
}

/* Sent-by-me styling (see chat_controller.js#applyBubbleStyling) - a subtle tinted background so
   "my" messages stay identifiable regardless of row position. color-mix against transparent (rather
   than --bs-primary-bg-subtle, which is a fairly saturated solid tone in dark mode) keeps the tint
   faint and blended with the page background in both themes. */
.chat-bubble-mine {
    background-color: color-mix(in srgb, var(--bs-primary) 12%, transparent);
    text-align: right;
}

/* Received-message zebra stripe, scoped to .chat-bubble-theirs specifically (rather than
   .chat-bubble:nth-child(even)) so it can never fight .chat-bubble-mine's background on
   specificity - the two classes are mutually exclusive per message, so there's nothing to win. */
.chat-bubble-theirs:nth-child(even) {
    background-color: var(--bs-tertiary-bg, #f8f9fa);
}

.chat-attachment-image {
    max-width: 240px;
    max-height: 240px;
}

.chat-compose-input-wrap {
    width: 100%;
}

.chat-compose-input {
    resize: none;
    max-height: 140px;
    overflow-y: auto;
    width: 100%;
    border-radius: 1.25rem;
    padding: 0.5rem 1rem;
    line-height: 1.4;
}

.chat-compose-btn {
    border-radius: 1.5rem;
    padding: 0.375rem 1.25rem;
}

.chat-compose-attach-link {
    font-size: 0.875rem;
    color: var(--bs-secondary-color, #6c757d);
    text-decoration: none;
}

.chat-compose-attach-link:hover {
    text-decoration: underline;
}

/* Bootstrap switches are sized in em's, so a larger switch is just a bigger font-size on the
   .form-check wrapper - see https://getbootstrap.com/docs/5.3/forms/checks-radios/#switches */
.form-switch-lg {
    font-size: 1.75rem;
}

/* @symfony/ux-dropzone's own stylesheet (vendor/symfony/ux-dropzone/assets/dist/style.min.css) sets
   this remove-file button's "×" via a raw UTF-8 character in its `content` value, which renders as
   mojibake ("Ã—") when that file is served with a non-UTF-8 charset. `\00D7` is the same character
   spelled as a pure-ASCII CSS escape, so it renders correctly regardless of the vendor file's
   charset - this doesn't need that file to be touched. Also gives the button a visible circular
   background instead of a bare glyph floating in the corner, and a title for accessibility/clarity. */
.dropzone-preview-button {
    top: 4px;
    right: 4px;
}

.dropzone-preview-button:before {
    /* !important: guarantees this wins over the vendor rule regardless of which stylesheet AssetMapper
       happens to emit later in <head> - both rules share the same selector/specificity otherwise. */
    content: "\00D7" !important;
    display: inline-flex !important;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.55);
    color: #fff;
    line-height: 1;
    font-size: 14px;
    padding: 0;
}

/* Responsive 16:9 wrapper for embedded video (see _macros/posts.html.twig's YouTube embed).
   The bare <iframe> it wraps has no explicit width/height, so without this it renders at the
   browser's ~300x150 default instead of scaling to the post width on any screen size. */
.video-container {
    position: relative;
    width: 100%;
    height: 0;
    padding-bottom: 56.25%;
    overflow: hidden;
}

.video-container iframe,
.video-container embed,
.video-container object {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    border: 0;
}

/* Bootstrap's offcanvas default width (--bs-offcanvas-width: 400px) is wider than many phone
   screens (e.g. iPhone SE at 375px), so the chat panel (#chatPanel, see
   templates/chat/_panel_shell.html.twig) would render wider than the viewport on small screens. */
@media (max-width: 400px) {
    #chatPanel {
        --bs-offcanvas-width: 100vw;
    }
}

/* Post header stat row (clock/privacy/upvotes/downvotes - see .post-meta-row in
   templates/_macros/posts.html.twig). At narrow widths the items' combined width can
   exceed the card, and being plain inline content they'd wrap onto a second line instead of
   staying a single row, so force nowrap and let the row scroll horizontally if it overflows. */
.post-meta-row {
    display: flex;
    flex-wrap: nowrap;
    align-items: center;
    overflow-x: auto;
    white-space: nowrap;
    scrollbar-width: none;
}

.post-meta-row::-webkit-scrollbar {
    display: none;
}

.post-meta-row span {
    flex: 0 0 auto;
}

/* Site-wide pagination styling, matching the pill look originally built for sktable
   (assets/core/sktable/sktable.css .sk-table-paging). Applies to every Bootstrap
   .pagination on the site (see templates/_partials/pagination.html.twig) so
   non-sktable pagination (e.g. drivers list, story stream) matches it too. */
.pagination {
    gap: 0.35rem;
}

.pagination .page-link {
    border-radius: 0.5rem !important;
    border-color: transparent;
    color: var(--bs-body-color);
    background-color: transparent;
    transition: background-color 0.12s ease-in-out, transform 0.12s ease-in-out;
}

.pagination .page-item:not(.disabled) .page-link:hover {
    background-color: var(--bs-tertiary-bg);
    transform: translateY(-1px);
}

.pagination .page-item.active .page-link {
    background-color: var(--bs-primary);
    border-color: var(--bs-primary);
    color: var(--bs-white, #fff);
    box-shadow: 0 0.15rem 0.4rem color-mix(in srgb, var(--bs-primary) 45%, transparent);
}

.pagination .page-item.disabled .page-link {
    /* Bootstrap's own `.disabled > .page-link` rule (bundled into styles.min.css, which loads
       after this file) ties this selector's specificity, so without an explicit background here
       the disabled state falls back to Bootstrap's solid --bs-pagination-disabled-bg box instead
       of fading out like every other non-active page-link. */
    background-color: transparent;
    color: var(--bs-secondary-color);
    opacity: 0.5;
}

/* Shrinks .pagination-compact page-links on narrow screens - shared by both
   templates/_partials/pagination.html.twig and sktable.js's pagination bar so the two
   look identical at every viewport width. */
@media (max-width: 400px) {
    .pagination-compact .page-link {
        padding: .25rem .45rem;
        font-size: .8rem;
    }
}

/* Suggestion chips rendered by slug_availability_controller.js after a taken slug is typed. */
.slug-availability-suggestions:empty {
    display: none;
}

.slug-availability-suggestions {
    margin-top: .35rem;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .35rem;
}

/* slug_availability_controller.js inserts the suggestions element directly after the <input> via
   insertAdjacentElement('afterend', ...) - when that input lives inside a Bootstrap .input-group
   (a flex container), that insert makes the suggestions block just another flex item, squeezing
   into the same row as the input instead of appearing below it like normal help text. Forcing it
   to consume the full row (Bootstrap's own documented trick for .invalid-feedback inside an
   .input-group, which also has flex-wrap: wrap) drops it onto its own line underneath instead.
   `order` is also needed: the suggestions div sits between the <input> and any trailing
   input-group element (e.g. a "Preview" button) in DOM order, so without a higher order that
   trailing element would wrap down onto the new line too, splitting the group's first row. */
.input-group > .slug-availability-suggestions {
    flex: 0 0 100%;
    order: 10;
    margin-top: .5rem;
}

.slug-availability-warning {
    color: var(--bs-warning-text-emphasis, #997404);
    font-size: .85rem;
}

.slug-availability-chip {
    border: 1px solid var(--bs-border-color);
    background: var(--bs-tertiary-bg, #f8f9fa);
    border-radius: 1rem;
    padding: .1rem .65rem;
    font-size: .85rem;
    line-height: 1.5;
    cursor: pointer;
}

.slug-availability-chip:hover {
    background: var(--bs-secondary-bg, #e9ecef);
}

/* MiPage card hover lift - used by both the pages listing (list_pages.html.twig, loaded via
   _base.html.twig) and the public MiPage directory (directory.html.twig, which extends the
   public layout directly and doesn't go through _base.html.twig), so this lives here rather
   than in either template's own addon_css block. */
.mp-page-card { transition: transform .15s ease, box-shadow .15s ease; }
.mp-page-card:hover { transform: translateY(-3px); box-shadow: 0 6px 16px rgba(0, 0, 0, .12); }
.mp-page-card__desc {
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
