/*
 * Bootstrap (imported in assets/app.js) carries the looks; this file only adds
 * what it does not cover. Prefer a Bootstrap class or utility in the templates
 * over a new rule here.
 */

/* Site theming hook (App\Twig\ThemeAwareLoader): a theme's
   templates/themes/<theme>/_theme_styles.html.twig redefines these variables
   to recolor/refont/repattern the page. Left at their defaults, a site with
   no theme (Site::$theme = null) looks exactly as before this file
   introduced them. */
:root {
    --theme-accent: var(--bs-body-color);
    --theme-font: var(--bs-body-font-family);
    --theme-bg: var(--bs-body-bg);
    --theme-header-bg: transparent;
    --theme-header-pattern: none;
    --theme-header-pattern-size: auto;
    --theme-card-accent-color: var(--bs-border-color-translucent);
    --theme-card-accent-width: var(--bs-border-width);
    --theme-card-bg: var(--bs-body-bg);
    --theme-detail-bg: transparent;
    --theme-detail-border-width: 0px;
    --theme-detail-padding: 0;
}

body {
    background-color: var(--theme-bg);
}

/* Public site header (base.html.twig). A plain `header` selector (not
   `header.border-bottom`) is deliberately lower specificity than the
   .bg-warning-subtle/.bg-info-subtle utility class base.html.twig adds on
   dev/test — that safety tint must always win over a theme's own background. */
header {
    background-color: var(--theme-header-bg);
    background-image: var(--theme-header-pattern);
    background-repeat: repeat-x;
    background-position: left bottom;
    background-size: var(--theme-header-pattern-size, auto);
}

/* The application is text first, so keep the reading width narrow — narrower
   than any Bootstrap breakpoint would give us. */
.container {
    max-width: 880px;
}

/* Article and location boxes (article/_grid.html.twig, article/_teaser.html.twig,
   location/index.html.twig — all plain Bootstrap .card). Re-asserting the top
   border only, at Bootstrap's own default width/color, is a no-op for an
   unthemed site; a theme thickening and recoloring it gets a brand-colored
   accent stripe. --theme-card-bg defaults to Bootstrap's own white card
   background, so an unthemed site is unaffected; a theme gives it a shade
   visibly darker than the page's own --theme-bg tint, so the card still
   reads as a distinct surface instead of blending into the page. */
.card {
    background-color: var(--theme-card-bg);
    border-top: var(--theme-card-accent-width) solid var(--theme-card-accent-color);
}

/* Article and location detail pages (article/show.html.twig,
   location/show.html.twig) — the same themed surface as the boxes above,
   sized for a full page of reading instead of a teaser. Every value defaults
   to a no-op (0 width, 0 padding, transparent) so an unthemed site's detail
   page is pixel-identical to before this rule existed; a theme only has to
   switch --theme-detail-* on, reusing the same colors it already set for
   --theme-card-*. */
.detail-box {
    background-color: var(--theme-detail-bg);
    border-top: var(--theme-detail-border-width) solid var(--theme-card-accent-color);
    border-radius: var(--bs-border-radius);
    padding: var(--theme-detail-padding);
}

/* Header brand mark (templates/_brand.html.twig / its theme overrides). */
.brand-link {
    color: var(--theme-accent) !important;
}

h1, h2, h3, h4, h5, h6 {
    font-family: var(--theme-font);
}

/* Language switcher in the header. */
.lang-switch a {
    margin-left: .4rem;
    font-size: .85rem;
    text-transform: uppercase;
    letter-spacing: .03em;
    color: var(--bs-secondary-color);
    text-decoration: none;
}

.lang-switch a.is-active {
    color: var(--theme-accent);
    font-weight: 700;
}

/* Article body: HTML written in the Trix editor, so the images and tables in it
   are not ours to add classes to. */
.article-content img {
    max-width: 100%;
    height: auto;
}

.article-content table {
    width: 100%;
}

/* The Trix editor is a form control of its own; make it look like the Bootstrap
   inputs around it. */
trix-editor {
    min-height: 12rem;
    border: var(--bs-border-width) solid var(--bs-border-color);
    border-radius: var(--bs-border-radius);
}

/* Admin edit forms (article, web, lokace): the save button stays where users
   expect it — at the end of the form — but fixed to the bottom of the
   viewport so it's always reachable without scrolling all the way down.
   .admin-sticky-form's own padding-bottom keeps the last field from hiding
   behind it. */
.admin-save-toolbar {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 1030;
    padding-block: .75rem;
    background: var(--bs-body-bg);
    border-top: var(--bs-border-width) solid var(--bs-border-color);
}

.admin-sticky-form {
    padding-bottom: 4.5rem;
}

/* Keep the toolbar visible while scrolling through a long article — it sticks
   to the top of the viewport until the editor (its containing block) scrolls
   past, then moves away with the rest of the form. No fixed site header exists
   to offset against, so top: 0 is enough. */
trix-toolbar {
    position: sticky;
    top: 0;
    z-index: 1020;
    background: var(--bs-body-bg);
}

/* Heading buttons added to the Trix toolbar (assets/controllers/trix_controller.js).
   Trix sizes only its own icon buttons, so give these the same box to keep the
   toolbar row even — including at the breakpoint where Trix makes its taller. */
trix-toolbar .trix-button--heading {
    width: 2.6em;
    height: 1.6em;
}

@media (max-width: 768px) {
    trix-toolbar .trix-button--heading {
        height: 2em;
    }
}

/* Clamped article content editor (assets/controllers/content_collapse_controller.js):
   collapsed shows ~2 lines of real text with the toolbar hidden (there is no
   room for it), expanded removes the limit and brings the toolbar back. The
   fade hints there is more below without needing the toolbar's height. */
.content-collapse:not(.is-expanded) .content-collapse-body {
    max-height: 10.6rem;
    overflow: hidden;
    position: relative;
}

.content-collapse:not(.is-expanded) .content-collapse-body::after {
    content: '';
    position: absolute;
    inset: auto 0 0 0;
    height: 1.5rem;
    background: linear-gradient(to bottom, transparent, var(--bs-body-bg));
    pointer-events: none;
}

.content-collapse:not(.is-expanded) .content-collapse-body trix-toolbar {
    display: none;
}

/* Leaflet needs an explicit height on its container (assets/controllers/location_map_controller.js) —
   it renders at 0 height otherwise. */
.location-map {
    height: 320px;
    border-radius: var(--bs-border-radius);
}

/* The pin drawn by location_map_controller.js replaces Leaflet's default
   marker image, which also carries its own drop shadow and background. */
.location-map-pin {
    background: none;
    border: none;
}

/* Place-search suggestions dropdown above the map in the admin point picker
   (assets/controllers/location_point_picker_controller.js) — sits over the
   map rather than pushing it down, and scrolls instead of growing forever. */
.location-search-results {
    z-index: 1000;
    max-height: 220px;
    overflow-y: auto;
}

/* Photo and per-location map side by side on the location list — a fixed,
   shorter height than .location-map so the pair sits in one compact row. */
.location-list-media {
    height: 160px;
}

/* Brief pulsing highlight on the article's audio player card when arrived at
   via the "🎧 Poslechnout" pill's #audio-player link (see
   article/_grid.html.twig and assets/controllers/audio_highlight_controller.js). */
@keyframes audio-player-pulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(var(--bs-primary-rgb), .5); }
    50% { box-shadow: 0 0 0 .75rem rgba(var(--bs-primary-rgb), 0); }
}

.audio-player-attention {
    animation: audio-player-pulse 1s ease-out 2;
}
